FrontEnd

React Router v7のSSRでパスルーティングな i18n をやってみた

投稿日:

はじめに

React Router v7がリリースされました🎉
また、remix-i18next も React Router v7対応されていたので、これらを組み合わせてパスルーティングなi18nをやってみました。

パスルーティングなi18nとは、パスに /en/ja が入ることで、言語を指定する方法の国際化対応です。今回はそれに加えて、言語が指定されていない場合にブラウザの言語に合わせて適切な言語切り替えができるようにしていきます。

remix-i18nextの導入

まずは、remix-i18nextを導入します。基本的には、remix-i18nのREADME.mdに沿って進めつつ、パスルーティングに必要な実装もしていきます。

インストール

まずは、以下のコマンドでパッケージを追加します。

パッケージが色々とありますが、全て必要なものです!

セットアップ

まず、翻訳ファイルを作成します。

public/locales/ja/common.json :

public/locales/en/common.json :

次に、i18nextの設定ファイルを作成します。今回は app/i18n.ts に作成します。

そして、Remix i18nextを使用するためのファイルを app/i18next.server.ts に作成します。

detectionの findLocale() 関数を実装していることで、パスによる言語切り替えができるようになっています。ここでnullをreturnすると、react-i18nextによって自動的に判定されます。その場合、デフォルトでは、 searchParams , cookie , session , header の優先度で判定が行われます。

headerを元にチェックする場合、リクエストヘッダの Accept-Language を元に判断されます。この値はページ遷移時にブラウザがリクエストヘッダに乗せてくれるため、ほとんどこの値を見るだけで正しく判断できると思います。

entry.server.tsxの実装

React Router v7でも引き続き entry.server.tsx は同じ役目を果たします。ここでは、先ほど作成した i18next.server.tsRemixi18Next による言語検知を使用しつつ、実際に各画面でi18nできるようにreact-i18nextの I18nextProvider をコンポーネントのトップ階層になるようにします。

entry.client.tsxの実装

こちらも、React Router v7でも引き続き同じ役目を果たします。こちらは、クライアントでのハイドレーションやページ内遷移、言語切り替えに対応するための実装になります。

一見、entry.server.tsxと似たコードですが、entry.server.tsxではremix-i18nextが生成したi18nextインスタンスに対して設定をしていたのに対し、こちらはi18nextを直接importし、それに対して設定をしています。

また、 .init() 内で設定されている detection.order に注目してください。今回は htmlTag が設定されていますが、これによりハイドレーション時に <html lang> を参照してくれるようになります。

i18n対応

ここからは、実際に各ページでi18n対応をしてみます。

root.tsxの実装

React Router v7でも root.tsx は健在です。このファイルでは、DOMのトップ階層を定義するための Layout や、アプリケーションとしてのトップ階層となる App を定義します。

SSRやハイドレーション時には、 i18nentry.server.tsx で検知された言語が入っているので、それを <html lang> に設定します。
次にAppを実装します。

今回、Appには言語切り替えリンクを実装してみました。言語を切り替えると、その言語用のパスに遷移しつつ、 i18n.changeLanguage() で実際に言語を切り替えます。
ちなみに、直接 /en/ja にアクセスする分には問題ありませんでしたが、ページ内遷移では言語は変更されず、そのため i18n.changeLanguage() する必要がありました。

その下に、indexページとsubpageを行き来するためのリンクも置いておきました。こちらは I18nLink という Link をラップしたコンポーネントを作り、パスの言語プレフィックスを維持したままリンクを生成するようにしてみました。

言語切り替えのためのルーティング

今回はパスを使った言語切り替えを実装したいと思います。

...prefix(":lang?") と定義することで、パスの先頭で言語を切り替えができるようになっています。また ? がついているので、この指定はあってもなくても良いことになっています。
今回は、indexページとsubpageを作ってみます。

実際にi18nしてみる

それでは、最後にindexページとsubpageを作り、実際に翻訳ファイル内のメッセージを表示してみます。
まずはindexページから。

subpageはこちら。ほぼ同じですが、表示するメッセージを変えてみます。

これで完成です。

さいごに

React Router v7でも無事、i18nすることができました。SSRとハイドレーションが絡むので考慮しなければならないことが多く苦労しました。

おすすめ書籍

Reactハンズオンラーニング 第2版 ―Webアプリケーション開発のベストプラクティス プログラミングTypeScript ―スケールするJavaScriptアプリケーション開発

blog-page_footer_336




blog-page_footer_336




-FrontEnd
-,

執筆者:

免責事項

このブログは、記事上部に記載のある投稿日時点の一般的な情報を提供するものであり、投資等の勧誘・法的・税務上の助言を提供するものではありません。仮想通貨の投資・損益計算は複雑であり、個々の取引状況や法律の変更によって異なる可能性があります。ブログに記載された情報は参考程度のものであり、特定の状況に基づいた行動の決定には専門家の助言を求めることをお勧めします。当ブログの情報に基づいた行動に関連して生じた損失やリスクについて、筆者は責任を負いかねます。最新の法律や税務情報を確認し、必要に応じて専門家に相談することをお勧めします。


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


関連記事

Next.js 入門してみた

1 はじめに1.1 なぜNext.jsなのか?2 Next.jsとは何か2.1 Static Site Generation (SSG)2.1.1 Incremental Static Regener ...

react-icon

React Konvaで状態管理されたCanvasを描画してみた

1 はじめに2 Canvasとは?3 React Konvaとは4 着せ替えアプリっぽいサンプルを作成4.1 React Konvaの導入4.2 画像の描画4.3 stateによるCanvas描画4. ...

【Vue.js】コンポーネントのテストコードをvue-test-utilsとJestで実装

1 はじめに2 セットアップ3 コンポーネントのテスト3.1 Shallow 描画3.2 基本的な例3.3 プロパティを渡す3.4 ユーザーの操作をシミュレーションする3.5 イベントを検証する3.6 ...

Vue.js入門その5〜マークダウンのリアルタイムプレビューをつくる〜

1 はじめに1.1 環境構築2 marked.jsの設定2.1 CDNのロード2.2 動作確認3 マークダウンを変換して表示3.1 雛形の作成3.1.1 HTML3.1.2 JS3.2 HTMLに変換 ...

react-icon

Vite 3を使ってみた

1 はじめに2 なぜViteは早いのか2.1 Native ESMの活用2.2 esbuildによる事前バンドル3 Viteのセットアップ3.1 Reactテンプレートでのセットアップ3.2 vite ...

フォロー

blog-page_side_responsive

2024年12月
1234567
891011121314
15161718192021
22232425262728
293031  

アプリ情報

私たちは無料アプリもリリースしています、ぜひご覧ください。 下記のアイコンから無料でダウンロードできます。