かめ。ブログ

mdxページ作成の簡易化

2023年10月1日

目次

方法

import remarkFrontmatter from 'remark-frontmatter';
import remarkMdxFrontmatter from 'remark-mdx-frontmatter';

/** @type {import('next').NextConfig} */
const withMDX = nextMDX({
  extension: /\.mdx$/,
  options: {
    remarkPlugins: [remarkFrontmatter, remarkMdxFrontmatter],
  },

使い方

const mdx = await import(`@/log/${params.post}.mdx`);
const data = mdx.frontmatter;
const default = mdx.default;

return (<mdx.default />);

npm run devでは動くのだが、下記の問題点が発生。

mdx.defaultでエラーになる

下記のmdx.defaultの形がserver側でエラーになる問題が解決できなかったため一旦use clientdynamicを使ってクライアント側で描画するようにしました。

const mdx = await import(`@/log/${params.post}.mdx`);
return (<mdx.default />);

dynamicを使用してクライアント側で描画するように

'use client';
import React, { forwardRef } from 'react';
import dynamic from 'next/dynamic';
import { Loading } from '@/components/ui/Loading';

type Props = {
  id: string;
  children?: React.ReactNode;
};

export const MdxContents = forwardRef<HTMLDivElement, Props>(
  function MdxContents({ children, id, ...rest }: Props, ref) {
    const DynamicComponentWithCustomLoading = dynamic(
      () => import(`@/log/${id}.mdx`),
      {
        loading: () => <Loading layout />,
      }
    );

    return <DynamicComponentWithCustomLoading />;
  }
);

idをpropsで渡して、コンポーネント内ではuse clientで動かして、dynamicmdxファイルを取得する仕組みにしました。