ReactおよびNext.jsでi18next JSONファイルを翻訳する方法 (2026)

来週の金曜日までに12言語でリリースする必要があるReactアプリを完成させたばかりだとします。ロケールファイルはpublic/locales/en/common.jsonにあり、ロケールごとに340個のキーがあり、文字列内のトークンはネストされたオブジェクト全体に{{userName}}や{{count}}のように散らばっています。JSONをChatGPTに貼り付けると、{{ nombreUsuario }}、余分なスペース、そして半分の複数形キーが名前変更されて返ってきます。アプリはビルド時にクラッシュします。
i18next JSONの翻訳を自動化しようとしたことがあれば、この苦痛がわかるでしょう。JSON形式は柔軟であるため、ほとんどの翻訳ツールがそれを台無しにしてしまいます。本当の問題は言語モデルの品質ではなく、消費者向けのAIツールがi18nextの構造ルールを理解していないことです。
このガイドでは、i18next JSONが他のロケール形式とどう違うのか、なぜ単純な翻訳アプローチがReactおよびNext.jsアプリを壊すのか、そして、すべてのキーを手動で確認することなく、何十ものロケールで安全に翻訳を自動化する方法を解説します。
i18next JSONとは何か、そしてなぜ翻訳が難しいのか
i18nextは、JavaScriptエコシステムで最も広く使用されているi18nライブラリです。React(react-i18next)、Next.js(next-i18next、App Router next-intl)、Vue、およびNodeバックエンドサービスを支えています。翻訳可能な文字列を、ロケールごとに1つのフラットまたはネストされたJSONファイルに保存します。
一般的なファイルは次のようになります。
{
"welcome": "Welcome, {{userName}}!",
"cart": {
"empty": "Your cart is empty",
"items_one": "{{count}} item in your cart",
"items_other": "{{count}} items in your cart"
},
"errors": {
"network": "Network error. <strong>Please retry</strong>."
}
}
これはシンプルに見えますが、3つの理由で汎用AIで翻訳するのは危険です。
補間トークンはテキストではなく構造的である
{{userName}}というシーケンスは単語ではなく、実行時にデータに置き換えられるプレースホルダーです。スペースを追加({{ userName }})、名前を変更、または内部識別子を翻訳すると、ランタイムはサイレントに失敗するかエラーをスローします。一部の翻訳者は親切にもスペイン語で{{count}}を{{conteo}}に変換します。あなたのアプリは、存在しない変数を補間しようとして、生のプレースホルダーをユーザーにレンダリングすることになります。
複数形キーは魔法の接尾辞である
i18nextは接尾辞_zero、_one、_two、_few、_many、_otherで複数形を検出します。これらは任意の文字列ではなく、ターゲットロケールのCLDR複数形カテゴリに一致する必要があります。英語は_oneと_otherのみを使用します。ロシア語、アラビア語、ポーランド語は最大6つのカテゴリを使用します。翻訳者が_otherを削除したり名前を変更したりすると、フォールバックチェーンが壊れます。
ネストされたキーは無傷でなければならない
フラットなキーと値のペアであるGettextの.poファイルとは異なり、i18nextファイルは任意にネストできます。怠惰な翻訳者は、構造をフラットにしたり、翻訳されたテキストに合わせてキー名を変更したり、オブジェクトを並べ替えたりするかもしれません。コード内のt('cart.items_other')の呼び出しは解決されなくなります。
開発者が最初に試す間違った解決策
どのチームも、本格的な解決策に投資する前に、同じ3段階の失敗サイクルを経験します。
ステージ1:ChatGPTに貼り付ける
200個のキーをChatGPTにコピーし、「このJSONをスペイン語に翻訳して」と尋ねて、結果を貼り付けます。180個のキーでは機能します。20個のキーは{{...}}の中にスペースが追加され、3個のキーは複数形の接尾辞が書き換えられ、1個の<strong>タグが<fuerte>に翻訳されてしまいます。ビルドが失敗するか、サイレントに壊れた文字列が本番環境にデプロイされます。
ステージ2:Google Translate API
Google Translate REST APIを連携させ、JSONを反復処理し、各値を送信します。速度は素晴らしいです。品質はそうではありません。GoogleのAPIは各文字列を孤立して扱います。アプリに関するコンテキストがなく、{{count}}がプレースホルダーであるという理解もなく、cart.emptyキーがcart.items_oneとは異なるという認識もありません。結局、すべてのキーについて人間によるレビューが必要です。
ステージ3:商用TMSプラットフォーム
翻訳管理システムに登録します。彼らは単語ごとに課金し、GitHub連携を必要とし、月額シートに縛り付けます。サイドプロジェクトやインディーアプリの場合、費用対効果はすぐに崩壊します。そして、彼らのエンジンがi18next形式を具体的に解析しない場合、同じプレースホルダー破損の問題に直面します。
同じ失敗モードはGettextワークフローでも現れます。コード変数を壊さずに.poファイルを翻訳する方法に関する当社のガイドは、WordPressおよびその他のGettextベースのスタックにおける同様の問題をカバーしています。
安全なアプローチ:構文認識型翻訳
i18next JSONを大規模に翻訳する唯一信頼できる方法は、まず形式を解析し、構文をロックし、翻訳可能なテキストのみをAIに送信するツールを使用することです。
構文認識処理が内部でどのように機能するかは次のとおりです。
- JSONを抽象ツリーに解析し、キーパスとネストを保持します。
- 補間トークン(
{{name}}、{{count, number}}、{{date, datetime}})を識別し、プレースホルダーIDに置き換えます。 - Transコンポーネント内のHTMLタグ(
<0>、<strong>、<br/>)を識別し、ロックします。 - 接尾辞によって複数形キーを検出し、ターゲットロケールのCLDRルールにマッピングします。
- クリーンアップされたテキストのみを、キーパスに関するコンテキストとともにLLMに送信します。
- 元のトークンとタグを正確な位置に再挿入します。
- 出力を検証します。プレースホルダーが欠落しているか、形式が不正な場合は、ソースに戻します。
これは、クラウドベースのPO翻訳を安全にするのと同じ原則です。基盤となるアーキテクチャに興味がある場合は、AI翻訳品質比較で、異なるLLMがこれらの制約をどのように処理するかを詳細に解説しています。
ステップバイステップ:SimplePoTranslateでi18next JSONを翻訳する
SimplePoTranslateは、ProおよびLifetimeプランでi18next JSONをネイティブにサポートしています。無料ティアでは現在.poおよび.potをカバーしています。JSONにアクセスするにはアップグレードするか、トライアルをご利用ください。
1. ソースファイルを準備する
英語(またはソースロケール)ファイルをマスターとして使用してください。それが有効なJSONであり、アプリが使用するすべてのキーを含んでいることを確認してください。よくある間違いは、古くなったキーや未使用のキーを残しておくことです。これは、決してレンダリングしない文字列のために翻訳クォータを消費してしまいます。
# From your project root
cp public/locales/en/common.json ~/Desktop/common.json
2. SimplePoTranslateにアップロードする
ダッシュボードにログインし、新しい翻訳をクリックしてcommon.jsonをアップロードします。プラットフォームはi18next形式を自動検出します。サポートされている41のロケールからターゲット言語を選択し、トーン(プロフェッショナル、カジュアル、マーケティング)を選択して送信します。
3. エンジンに任せる
内部では、ファイルは解析され、安全なバッチに分割され、並行して翻訳されます。補間トークンはロックされます。複数形の接尾辞は保持され、ターゲットロケールのCLDRルールにマッピングされます。Transコンポーネント内のHTMLは無傷のままです。
4. ZIPをダウンロードする
翻訳されたJSONと、代替形式(PHPアプリ用の.php、ツール間互換性用の.po)を含むZIPファイルが返されます。JSONをpublic/locales/es/common.jsonに配置して再デプロイします。
unzip common_es.zip
mv common.json public/locales/es/common.json
npm run build
5. 繰り返すかバッチ処理する
12のターゲットロケールすべてに対して、12個のジョブを送信します。Proプランのクォータは、数十の典型的なSaaSアプリをカバーします。複数の名前空間ファイルを持つモノレポの場合、それぞれを個別にアップロードするか、順次バッチ処理します。
翻訳の統合をアプリへの再統合
JSONファイルを翻訳したら、統合は簡単な部分です。いくつかの注意点:
- 複数カテゴリを確認する。 ロケールごとに簡単なスモークテストを実行します:
count={0}、count={1}、count={5}でコンポーネントをレンダリングし、3つすべてが正しい文字列を生成することを確認します。 - RTLロケールを確認する。 アラビア語、ヘブライ語、ペルシャ語に翻訳した場合、UIにはRTL対応CSSが必要です。WordPress RTL翻訳ガイドでは、Reactアプリにも適用されるCSSパターンをカバーしています。
- フォールバックチェーンを設定する。 キーが欠落している場合にi18nextが英語にフォールバックするように設定し、デプロイ途中の状態がユーザーをクラッシュさせないようにします。
- CIでソースファイルをロックする。
en/common.jsonが他のロケールを再生成せずに変更されるPRを拒否するチェックを追加します。翻訳のずれは、本番環境でのi18nバグの最大の原因です。
React、Next.js、およびサーバーサイドで展開するチームにとって、1つのソースからすべての形式を生成できることは大きな利点です。1つのファイルから5つの形式を生成する方法に関する当社の記事では、マルチフォーマット出力が長期的なメンテナンスにとって重要である理由を説明しています。
JSONだけでは不十分な場合:複雑なケースの処理
いくつかのエッジケースには特別な注意が必要です。
ICU MessageFormat
プロジェクトでICU構文({count, plural, one {1 item} other {# items}})を使用している場合、i18nextはこれを補間として扱いますが、構造はより複雑です。翻訳ツールがICUパラメータを認識し、one、otherなどのカテゴリ名や、plural、number、dateなどの形式識別子を翻訳しないことを確認してください。
TransコンポーネントとReactノード
<Trans>は、インデックス(<0>、<1>)によってキー付けされた翻訳済み文字列内にReactコンポーネントをレンダリングします。翻訳者は正確なタグ順序を保持する必要があります。SimplePoTranslateの構文ロック機能がこれを処理しますが、別のツールを使用する場合は、リリース前に確認してください。
名前空間ファイル
大規模なアプリでは、ロケールをcommon.json、dashboard.json、checkout.jsonなどの名前空間に分割します。各ファイルを個別に翻訳し、マージしないでください。各名前空間のキーパスがスコープ内に維持されていると、コンテキストの品質が高くなります。
まとめ
ReactまたはNext.jsアプリ用のi18next JSONの翻訳は、最高のAIモデルを選ぶことではありません。それは、補間、複数形の接尾辞、ネストされたキー、HTMLタグといった形式の構造ルールが、往復処理後も維持されることです。消費者向けAIツールはJSONを非構造化テキストとして扱います。構文認識ツールはそれを構造化データとして解析し、翻訳可能な部分のみを扱います。
多言語アプリをリリースしていて、JSONをチャットインターフェースにコピー&ペーストしていたとしたら、そのコストはすでに知っているはずです。ロケールごとに何時間もの手動レビュー、ランダムな本番環境のバグ、そして壊れた複数形が積み重なるばかりです。形式認識パイプラインは、これらの失敗モードのすべてを取り除きます。
i18next JSONファイルを安全に翻訳する準備はできていますか?SimplePoTranslateを無料でお試しください - クレジットカードは不要です。一度アップロードすれば、41言語でリリースできます。