言語ベースのルーティング
Next.js(Appルーター)での言語ベースのルーティングの設定
問題
複数の言語をサポートするアプリケーションでは、/aboutのような単一のURLは本質的に曖昧です。このURLにアクセスするユーザーはデフォルト言語でコンテンツを受け取りますが、異なる言語バージョンのページにリンクしたりブックマークしたりする方法がありません。この曖昧さは検索エンジンも混乱させ、すべての言語バージョンがインデックスされなかったり、混在したりする可能性があります。
解決策
URLパスに直接言語識別子を組み込みます(例:/en/aboutや/fr/about)。これにより、すべてのパスが特定の言語に固有のものとなり、ユーザーと検索エンジンの両方にとっての曖昧さが解消されます。
手順
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>
);
}
この関数はNext.jsにアプリが/en、/es、/frをサポートしていることを通知します。他のパス(/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パラメータはすべてのページで利用可能です。