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ファイルを自動的にプリレンダリングします。