Next13のApp RouterでMDXを直接ページにする方法

2023/04/23に公開

Next.jsのApp Router (app directory)でMDXを使用したくて調べました。ほぼ公式のドキュメント通りなのですが、MDXファイルを直接ページとして表示するためには追加の設定が必要だったので、備忘録として手順を残します。

結論

  • @next/mdx をインストールして設定する
  • nextjs.config.jsの pageExtensions'mdx' を追加する

詳細な手順

0. App Routerを有効にする

App Routerが有効になっていることを確認します。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
}

module.exports = nextConfig

1. @next/mdx をインストールする

Peer Dependencies もまとめてインストールします。 ( @mdx-js/loader は無いと動きませんでした)

npm install @next/mdx @mdx-js/loader @mdx-js/react

のちのち使用する型定義があるので、 @types/mdx もインストールしておくと良いです。

npm install @types/mdx

2. プロジェクトのルートに mdx-components.tsx を追加する

ドキュメントのコードそのままです。

mdx-components.tsx
import type { MDXComponents } from 'mdx/types'
    // This file is required to use MDX in `app` directory.
    export function useMDXComponents(components: MDXComponents): MDXComponents {
      return {
        // Allows customizing built-in components, e.g. to add styling.
        // h1: ({ children }) => <h1 style={{ fontSize: "100px" }}>{children}</h1>,
        ...components,
      }
    }

3. next.config.jsにwithMDXの設定を行う

next.config.js
const withMDX = require('@next/mdx')()

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    appDir: true,
  },
}

module.exports = withMDX(nextConfig)

ここまで設定すれば、page.tsxからmdxファイルをインポートすることでmdxファイルを表示できるようになります。mdxファイルを直接ページとして表示するためには、さらに次の手順が必要です。

4. pageExtensions'mdx' を追加

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['tsx', 'mdx'], // ここを追加
  experimental: {
    appDir: true,
  },
}

module.exports = withMDX(nextConfig)

5. MDXファイルをページとして使用する (完了)

app/about/page.mdx を作成すると、/about ページとして表示されます。ルートレイアウト (app/layout.tsx) も、もちろん反映されます。

app/hello.mdx
## About

This is a demo for rendering MDX as a page.

mdx as page

6. (オプション) mdxRs を有効にする

mdxRsを有効にすると、Rustを使用してmdxファイルをコンパイルするのでビルドが高速になります。

next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['tsx', 'mdx'],
  experimental: {
    appDir: true,
    mdxRs: true, // ここを追加
  },
}

module.exports = withMDX(nextConfig)

補足: MDXファイルをコンポーネントとして使用する

ドキュメントに記載されている方法です。mdxファイルをコンポーネントとしてインポートできるので、page.tsx ファイルでインポートして使用することで、MDXのコンテンツを表示できます。

contents/sample-text.mdx
## Sample Text

This is a demo for rendering MDX as a server component.
pages/hello.tsx
import SampleText from "@/contents/sample-text.mdx"

export default function Home() {
  return <SampleText />
}

mdx as component

おわり

App Router楽しいですね。MDXをページとして使用するサンプルを置いておくのでご自由にお使いください。

sushidesu/next-app-router-with-mdx-page: next-app-router-with-mdx-page

参考

GitHubで編集を提案
プラハのブログ

Discussion