Next.jsでの国際化 (i18n) 実装方法
サンプル
Next.jsはv10.0.0
以降、国際化(i18n)ルーティングを組み込みでサポートしています。ロケールのリスト、デフォルトロケール、ドメイン固有のロケールを提供することで、Next.jsが自動的にルーティングを処理します。
i18nルーティングサポートは現在、react-intl
、react-i18next
、lingui
、rosetta
、next-intl
、next-translate
、next-multilingual
、tolgee
、paraglide-next
、next-intlayer
などの既存のi18nライブラリソリューションを補完することを目的としており、ルートとロケール解析を合理化します。
はじめに
まず、next.config.js
ファイルにi18n
設定を追加します。
ロケールはUTSロケール識別子で、ロケールを定義する標準化された形式です。
一般的にロケール識別子は、言語、地域、スクリプトをダッシュで区切って構成されます: language-region-script
。地域とスクリプトはオプションです。例:
en-US
- アメリカで話されている英語nl-NL
- オランダで話されているオランダ語nl
- オランダ語、特定の地域なし
ユーザーのロケールがnl-BE
で、設定にリストされていない場合、利用可能であればnl
にリダイレクトされ、それ以外の場合はデフォルトロケールにリダイレクトされます。
国のすべての地域をサポートする予定がない場合は、フォールバックとして機能する国別ロケールを含めることが良いプラクティスです。
ロケール戦略
ロケール処理には2つの戦略があります: サブパスルーティングとドメインルーティング。
サブパスルーティング
サブパスルーティングでは、ロケールをURLパスに配置します。
上記の設定では、en-US
、fr
、nl-NL
がルーティング可能で、en-US
がデフォルトロケールです。pages/blog.js
がある場合、次のURLが利用可能になります:
/blog
/fr/blog
/nl-nl/blog
デフォルトロケールにはプレフィックスがありません。
ドメインルーティング
ドメインルーティングを使用すると、異なるドメインからロケールを提供するように設定できます:
例えば、pages/blog.js
がある場合、次のURLが利用可能になります:
example.com/blog
www.example.com/blog
example.fr/blog
example.nl/blog
example.nl/nl-BE/blog
自動ロケール検出
ユーザーがアプリケーションのルート(通常は/
)にアクセスすると、Next.jsはAccept-Language
ヘッダーと現在のドメインに基づいて、ユーザーが好むロケールを自動的に検出しようとします。
デフォルトロケール以外のロケールが検出された場合、ユーザーは次のいずれかにリダイレクトされます:
- サブパスルーティングを使用する場合: ロケールプレフィックス付きのパス
- ドメインルーティングを使用する場合: そのロケールがデフォルトとして指定されているドメイン
ドメインルーティングを使用する場合、Accept-Language
ヘッダーがfr;q=0.9
のユーザーがexample.com
にアクセスすると、そのドメインがデフォルトでfr
ロケールを処理するため、example.fr
にリダイレクトされます。
サブパスルーティングを使用する場合、ユーザーは/fr
にリダイレクトされます。
デフォルトロケールにプレフィックスを追加
Next.js 12とミドルウェアを使用すると、回避策でデフォルトロケールにプレフィックスを追加できます。
例えば、以下はいくつかの言語をサポートするnext.config.js
ファイルです。"default"ロケールが意図的に追加されていることに注意してください。
次に、ミドルウェアを使用してカスタムルーティングルールを追加できます:
このミドルウェアは、APIルートとフォントや画像などのパブリックファイルにデフォルトプレフィックスを追加するのをスキップします。デフォルトロケールへのリクエストがある場合、プレフィックス/en
にリダイレクトします。
自動ロケール検出の無効化
自動ロケール検出は次のように無効にできます:
localeDetection
をfalse
に設定すると、Next.jsはユーザーの優先ロケールに基づいて自動的にリダイレクトしなくなり、上記で説明したロケールベースのドメインまたはロケールパスから検出されたロケール情報のみを提供します。
ロケール情報へのアクセス
Next.jsルーターを介してロケール情報にアクセスできます。例えば、useRouter()
フックを使用すると、次のプロパティが利用可能です:
locale
- 現在アクティブなロケールを含むlocales
- 設定されているすべてのロケールを含むdefaultLocale
- 設定されているデフォルトロケールを含む
getStaticProps
またはgetServerSideProps
でページをプリレンダリングする場合、ロケール情報は関数に提供されるコンテキストで提供されます。
getStaticPaths
を活用する場合、設定されたロケールは関数のコンテキストパラメータのlocales
の下で提供され、設定されたdefaultLocale
はdefaultLocale
の下で提供されます。
ロケール間の遷移
next/link
またはnext/router
を使用してロケール間を遷移できます。
next/link
の場合、locale
プロップを提供して、現在アクティブなロケールから別のロケールに遷移できます。locale
プロップが提供されない場合、クライアント遷移中に現在アクティブなlocale
が使用されます。例えば:
next/router
メソッドを直接使用する場合、遷移オプションを介して使用するべきlocale
を指定できます。例えば:
ダイナミックルートクエリ値や非表示のhrefクエリ値などのすべてのルーティング情報を保持しながらロケールのみを切り替えるには、href
パラメータをオブジェクトとして提供できます:
router.push
のオブジェクト構造の詳細についてはこちらを参照してください。
ロケールがすでに含まれているhref
がある場合、ロケールプレフィックスの自動処理をオプトアウトできます:
NEXT_LOCALE
クッキーの活用
Next.jsでは、NEXT_LOCALE=the-locale
クッキーを設定でき、これはaccept-languageヘッダーよりも優先されます。このクッキーは言語スイッチャーを使用して設定でき、ユーザーがサイトに戻ってきたときに、/
から正しいロケールの場所にリダイレクトする際にクッキーで指定されたロケールが使用されます。
例えば、ユーザーのaccept-languageヘッダーがfr
を好むが、NEXT_LOCALE=en
クッキーが設定されている場合、/
にアクセスすると、クッキーが削除または期限切れになるまで、ユーザーはen
ロケールの場所にリダイレクトされます。
検索エンジン最適化
Next.jsはユーザーが訪問している言語を知っているため、自動的に<html>
タグにlang
属性を追加します。
Next.jsはページのバリエーションを知らないため、next/head
を使用してhreflang
メタタグを追加するのはあなた次第です。hreflang
の詳細についてはGoogleウェブマスター向けドキュメントで学べます。
静的生成との連携方法
国際化ルーティングはNext.jsのルーティングレイヤーを活用しないため、
output: 'export'
とは統合されません。output: 'export'
を使用しないハイブリッドNext.jsアプリケーションは完全にサポートされます。
ダイナミックルートとgetStaticProps
ページ
ダイナミックルートを使用するgetStaticProps
ページの場合、プリレンダリングしたいページのすべてのロケールバリアントをgetStaticPaths
から返す必要があります。paths
に対して返されるparams
オブジェクトと共に、どのロケールをレンダリングしたいかを指定するlocale
フィールドも返せます。例えば:
自動静的最適化および非ダイナミックなgetStaticProps
ページの場合、各ロケールに対してページのバージョンが生成されます。これは、getStaticProps
内で設定されているロケールの数に応じてビルド時間が増加する可能性があるため、考慮することが重要です。
例えば、50のロケールが設定されており、getStaticProps
を使用する10の非ダイナミックページがある場合、getStaticProps
は500回呼び出されます。ビルドごとに10ページの50バージョンが生成されます。
getStaticProps
を使用するダイナミックページのビルド時間を短縮するには、fallback
モードを使用します。これにより、ビルド時にプリレンダリングするためだけにgetStaticPaths
から最も人気のあるパスとロケールを返すことができます。その後、Next.jsはリクエスト時に残りのページをビルドします。
自動静的最適化ページ
自動的に静的に最適化されるページの場合、各ロケールに対してページのバージョンが生成されます。
非ダイナミックなgetStaticPropsページ
非ダイナミックなgetStaticProps
ページの場合、上記のように各ロケールに対してバージョンが生成されます。getStaticProps
はレンダリングされる各locale
で呼び出されます。特定のロケールをプリレンダリングから除外したい場合は、getStaticProps
からnotFound: true
を返すと、そのバリアントのページは生成されません。
i18n設定の制限
locales
: 合計100ロケールdomains
: 合計100ロケールドメイン項目
知っておくと良い: これらの制限は、最初にビルド時の潜在的なパフォーマンス問題を防ぐために追加されました。Next.js 12ではミドルウェアを使用したカスタムルーティングでこれらの制限を回避できます。