Next.jsにおけるi18nの静的レンダリングと動的レンダリングの比較
next-intlに関する問題
何が起こるのか? i18nルーティングされたアプリ(/en/…、/fr/…)のサーバーコンポーネント内でuseTranslations、getTranslations、または任意のnext-intlヘルパーを使用すると、Next.jsはそのルート全体を動的としてマークします。([Next Intl][1])
なぜか? next-intlは、リクエスト専用ヘッダー(x-next-intl-locale)からheaders()を介して現在のロケールを取得します。headers()は動的APIであるため、それに触れるコンポーネントは静的最適化を失います。([Next Intl][1], [Next.js][2])
公式の回避策(ボイラープレート)
- サポートされているすべてのロケールでgenerateStaticParamsをエクスポートします。
- useTranslationsを呼び出す前に、すべてのレイアウト/ページでsetRequestLocale(locale)を呼び出します。([Next Intl][1]) これによりヘッダー依存がなくなりますが、追加のコード管理が必要になり、本番環境で不安定なAPIとなります。
intlayerが問題を回避する方法
設計上の選択
- ルートパラメータのみ – ロケールはNext.jsがすでに各ページに渡している[locale]のURLセグメントから取得されます。
- コンパイル時バンドル – 翻訳は通常のESモジュールとしてインポートされるため、ツリーシェイクされビルド時に埋め込まれます。
- 動的APIなし – useT()はheaders()やcookies()からではなく、Reactコンテキストから読み取ります。
- 追加設定不要 – ページがapp/[locale]/配下にあると、Next.jsはロケールごとに1つのHTMLファイルを自動的にプリレンダリングします。