はじめに
Nextra 4がリリースされ、Nextra2で作成したサイトをNextra4に移行を試みていたのですが、改善点が多く上手くアップグレード出来なかった。
そのため、Nextra2のプロジェクトを更新するのではなく、Nextra4のプロジェクトを作成し、Nextra2のプロジェクトをNextra4のプロジェクトに移行することにしました。
この記事では、Nextra 2からNextra 4へマイグレーションする際に必要な変更点を解説します。
1. ルーター変更: Pages Router → App Router
最も大きな変更点はルーターです。
| バージョン | ルーター | ディレクトリ |
|---|---|---|
| Nextra 2 | Pages Router | pages/ |
| Nextra 4 | App Router | app/ |
Nextra 4はNext.js App Routerのみをサポートしています。pages/配下のMDXファイルはapp/に移動する必要があります。
2. next.config の設定変更
Nextra 2
const withNextra = require('nextra')({
theme: 'nextra-theme-docs',
themeConfig: './theme.config.tsx',
})
module.exports = withNextra({})Nextra 4
import nextra from "nextra";
const withNextra = nextra({});
export default withNextra({
turbopack: {
resolveAlias: {
"next-mdx-import-source-file": "./mdx-components.js",
},
},
});主な変更点:
themeとthemeConfigオプションは廃止- CommonJS → ESM import形式に変更
- Turbopack使用時は
resolveAlias設定が必須
3. テーマ設定の移行: theme.config.tsx → app/layout.tsx
Nextra 2: theme.config.tsx
export default {
logo: <span>My Docs</span>,
project: { link: 'https://github.com/...' },
footer: { text: 'MIT 2024' },
}Nextra 4: app/layout.tsx
import { Footer, Layout, Navbar } from "nextra-theme-docs";
import { Head } from "nextra/components";
import { getPageMap } from "nextra/page-map";
import "nextra-theme-docs/style.css";
const navbar = <Navbar logo={<b>My Documentation</b>} />;
const footer = <Footer>MIT {new Date().getFullYear()} © My Documentation.</Footer>;
export default async function RootLayout({ children }) {
return (
<html lang="ja" dir="ltr" suppressHydrationWarning>
<Head />
<body>
<Layout
navbar={navbar}
pageMap={await getPageMap()}
docsRepositoryBase="https://github.com/..."
footer={footer}
>
{children}
</Layout>
</body>
</html>
);
}主な変更点:
- テーマ設定は
Layoutコンポーネントのpropsとして渡す pageMapはgetPageMap()関数で取得- CSSは明示的にimportが必要(
nextra-theme-docs/style.css)
4. mdx-components.js が必須に
Nextra 4では、プロジェクトルートにmdx-components.jsファイルが必須になりました。
import { useMDXComponents as getThemeComponents } from "nextra-theme-docs";
const themeComponents = getThemeComponents();
export function useMDXComponents(components) {
return {
...themeComponents,
...components,
};
}このファイルがないと、以下のエラーが発生します:
Module not found: Can't resolve 'next-mdx-import-source-file'5. _meta ファイルの形式変更
Nextra 2: _meta.json(JSON形式)
{
"index": "Introduction",
"getting-started": "Getting Started"
}Nextra 4: _meta.js(ESM形式)
export default {
index: "Introduction",
"getting-started": "Getting Started",
};ファイル名も_meta.jsonから_meta.jsに変更されています。
6. MDXファイルの配置規則
| バージョン | パス例 |
|---|---|
| Nextra 2 | pages/docs/index.mdx |
| Nextra 4 | app/docs/page.mdx または content/docs/index.mdx |
App Routerではpage.mdxという命名規則に従うか、content/ディレクトリを使用できます。
7. インポートパスの変更
| 用途 | Nextra 4 |
|---|---|
| テーマコンポーネント | nextra-theme-docs |
| Banner, Head等 | nextra/components |
| getPageMap | nextra/page-map |
| テーマCSS | nextra-theme-docs/style.css |
8. 静的エクスポート設定
静的サイトとしてエクスポートする場合、next.config.tsに以下の設定が必要です。
export default withNextra({
output: "export", // out/ ディレクトリに静的ファイルを出力
images: {
unoptimized: true, // 静的エクスポート時は画像最適化を無効化
},
});output: "export" を設定すると、npm run build 実行時に out/ ディレクトリにビルド結果が出力されます。
9. 検索機能(Pagefind)の設定
Nextra 4では検索機能にPagefind
を使用します。
ビルド後に検索インデックスを生成する必要があります。
インストール
npm install -D pagefindpackage.json の設定
{
"scripts": {
"build": "next build",
"postbuild": "pagefind --site out --output-path out/_pagefind"
}
}postbuild スクリプトは npm run build 完了後に自動実行されます。
注意点:
--site out: 静的エクスポート先のディレクトリを指定--output-path out/_pagefind: 検索インデックスの出力先output: "export"を設定していない場合は--site .next/server/appを使用
検索が動作しない場合
output: "export"が設定されているか確認postbuildの--siteパスがoutになっているか確認- ビルド後に
out/_pagefind/ディレクトリが作成されているか確認
まとめ
| 項目 | Nextra 2 | Nextra 4 |
|---|---|---|
| ルーター | Pages Router | App Router |
| テーマ設定 | theme.config.tsx | app/layout.tsx |
| MDXコンポーネント | 不要 | mdx-components.js必須 |
| メタファイル | _meta.json | _meta.js |
| nextra設定 | theme, themeConfig | 空オブジェクトまたはmdxOptions |
| 検索エンジン | FlexSearch (組み込み) | Pagefind (要設定) |
| ビルド出力 | .next/ | out/ (静的エクスポート時) |