言語ベースのルーティング
Next.js (App Router) で言語ベースのルーティングを設定する
問題
アプリケーションが複数の言語をサポートしている場合、/about のような単一の URL は本質的に曖昧です。この URL にアクセスするユーザーはデフォルト言語のコンテンツを受け取りますが、そのページの別の言語バージョンにリンクしたりブックマークしたりする方法がありません。この曖昧さは検索エンジンを混乱させ、すべての言語バージョンがインデックスされなかったり、それらが混在したりする可能性があります。
解決策
/en/about や /fr/about のように、言語識別子を URL パスに直接組み込みます。これにより、すべてのパスが特定の言語に固有のものとなり、ユーザーと検索エンジンの両方にとって曖昧さが解消されます。
手順
1. 動的言語セグメントを作成する
Next.js App Router では、app ディレクトリのルートに動的セグメントフォルダを作成することで言語ルーティングを処理します。app 内に [lang] という名前の新しいフォルダを作成し、メインの page.tsx ファイルをその中に移動します。
// app/[lang]/page.tsx
export default function Home({ params }: { params: { lang: string } }) {
return (
<div>
<h1>Home page</h1>
<p>Current language: {params.lang}</p>
</div>
);
}
この [lang] フォルダは URL の最初の部分(例: 'en' や 'fr')をキャプチャし、それを params オブジェクト内の lang プロパティとしてページコンポーネントに渡します。これで、/en や /fr のような URL でページにアクセスできるようになります。
2. ルートレイアウトを更新する
ルートの layout.tsx も app/[lang] フォルダ内に移動する必要があります。これも lang パラメータを受け取るため、アクセシビリティと SEO のために <html> タグの lang 属性を設定するために使用する必要があります。
// app/[lang]/layout.tsx
export default function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
);
}
このレイアウトは、特定の言語内のすべてのページをラップします。ここでlang属性を設定することで、ページコンテンツがどの言語であるかをブラウザに通知します。
3. サポートする言語を定義する
Next.jsにどの言語セグメントが有効かを伝えるには、ルートレイアウトからgenerateStaticParams関数をエクスポートします。これにより、Next.jsはビルド時にこれらのルートを静的に生成できます。
// app/[lang]/layout.tsx
export async function generateStaticParams() {
return [{ lang: 'en' }, { lang: 'es' }, { lang: 'fr' }];
}
export default function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
return (
<html lang={params.lang}>
<body>{children}</body>
</html>
);
}
この関数は、アプリが/en、/es、/frをサポートしていることをNext.jsに通知します。他のパス(/deなど)へのリクエストは、404 Not Foundページになります。
4. ネストされたルートを追加する
アプリ内の他のすべてのページは、[lang]フォルダ内に作成されます。たとえば、「about」ページを作成するには、app/[lang]/about/page.tsxを追加します。
// app/[lang]/about/page.tsx
export default function AboutPage({ params }: { params: { lang: string } }) {
return (
<div>
<h1>About page</h1>
<p>Current language: {params.lang}</p>
</div>
);
}
このファイルは、/en/about、/es/about、/fr/aboutでアクセス可能なルートを自動的に作成します。正しい翻訳コンテンツを取得する必要がある場合、langパラメータはすべてのページで利用できます。