国際化ファイルチェック
開発ツール
読み込み中
ツールを読み込んでいます
ツールのコードは開いたときにのみ読み込まれます。
このツールの処理はすべてブラウザー内で行われ、入力内容はサーバーへ送信されません。
このツールについて
翻訳を公開する前に、基準言語と対象言語のファイルを構造として比較します。入れ子のオブジェクト、空のコンテナー、JSON の型を保持し、不足キー・余分なキー・不一致を JSON Pointer の位置で報告します。プレーンテキスト、波括弧引数、明示的に限定した ICU-flat を選べます。テンプレートの描画や実行は行わず、訳文や基本型の具体的な値は比較しません。構造の確認を助けるツールであり、翻訳品質の採点や各フレームワークの完全な互換性検証ではありません。
主な用途
- 翻訳ファイルのマージ後に、足りないメニュー名、対象側に残った古いキー、文字列からオブジェクトへ誤って変わった項目を探す。
- 通常の訳文の違いをエラーにせず、アプリケーションが使う名前付き引数や位置引数が訳文にも残っているか確認する。
- 言語ごとのカテゴリーで単層の基数・序数メッセージを調べ、位置付き JSON レポートを翻訳レビューに利用する。
使い方
- 1.基準側と対象側の UTF-8 JSON を貼り付けるか、ファイルを開きます。ルートは両方ともオブジェクトが必要です。プレーンテキストから始めるか、波括弧・ICU-flat を明示的に選びます。ICU-flat では各側の実際の言語タグを指定します。
- 2.ファイル形式に索引比較が合う場合だけ配列を許可し、それ以外は既定の配列拒否を使います。検査後に側・問題の種類・ページで絞り込みます。不足した部分木は、コンテナーと各子孫パスをそれぞれ報告します。
- 3.全件を確認し、JSON レポートをコピーまたはダウンロードします。画面の絞り込みやページは出力を減らしません。入力・比較設定を変えると古い結果は無効になり、上限に達した場合は範囲を小さくして再検査が必要です。
再現可能な国際化チェック例
プレーンでは訳文と具体値を無視
reference:
{"greeting":"Hello {name}","count":1,"enabled":true,"empty":{}}
target:
{"greeting":"こんにちは {broken","count":99,"enabled":false,"empty":{}}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[]}訳文・数字・真偽値が異なっても型は同じです。プレーンモードは閉じていない括弧も意図的に検査しないため、この要約には問題がありません。
不足・余分なパスと型の変更
reference:
{"menu":{"home":"Home","gone":"Old"},"count":1,"empty":{}}
target:
{"menu":{"home":"首页","extra":"New"},"count":"1","empty":[]}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"indices"}{"valid":true,"issues":[{"code":"missing-key","path":"/menu/gone","side":"before","severity":"error"},{"code":"type-mismatch","path":"/count","side":"after","severity":"error"},{"code":"type-mismatch","path":"/empty","side":"after","severity":"error"},{"code":"extra-key","path":"/menu/extra","side":"after","severity":"error"}]}対象側には /menu/gone がなく、/menu/extra が増えています。数字が文字列、空オブジェクトが空配列になり、明示的な索引モードで配列も検査します。
不足した部分木にはコンテナーも含む
reference:
{"group":{"title":"Title"},"empty":{}}
target:
{}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"missing-key","path":"/group","side":"before","severity":"error"},{"code":"missing-key","path":"/group/title","side":"before","severity":"error"},{"code":"missing-key","path":"/empty","side":"before","severity":"error"}]}基準側の group、その title、独立した空オブジェクトにはそれぞれパスがあります。対象側にはすべてなく、空のコンテナーも見落としません。
JSON Pointer と特殊な名前のキー
reference:
{"a/b":{"~name":"x"},"a.b":"x","__proto__":"text","constructor":{}}
target:
{"a/b":{},"a.b":"y","__proto__":"译文","constructor":{}}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"missing-key","path":"/a~1b/~0name","side":"before","severity":"error"}]}不足しているのは a/b 内の ~name で、位置は /a~1b/~0name です。リテラルの a.b、__proto__、constructor は独立した通常のデータです。
エスケープ展開後の重複キーを拒否
reference:
{"title":"One","ti\u0074le":"Two"}
target:
{}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":false,"issues":[{"code":"duplicate-key","path":"/title","side":"before","severity":"error"}]}title と ti\u0074le は同じ名前になります。最後の値を黙って採用せず基準入力を拒否し、比較とレポート出力を止めます。
既定の配列拒否は両側を診断
reference:
{"steps":["A","B"]}
target:
{"steps":["一"]}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":false,"issues":[{"code":"arrays-rejected","path":"/steps","side":"before","severity":"error"},{"code":"arrays-rejected","path":"/steps","side":"after","severity":"error"}]}両方のファイルの /steps に配列があります。既定の拒否設定はキー比較の前に各側を診断し、配列要素をオブジェクトキーとして扱いません。
明示的なゼロ始まりの索引比較
reference:
{"steps":["A","B"]}
target:
{"steps":["一"]}
options:
{"mode":"plain","beforeLocale":"en","afterLocale":"ja","arrays":"indices"}{"valid":true,"issues":[{"code":"missing-key","path":"/steps/1","side":"before","severity":"error"}]}索引モードでは、最初の要素は訳文が違っても同じ文字列型です。基準側の 2 番目の要素が対象側になく、/steps/1 に不足を報告します。
二重括弧のリテラルと引数集合
reference:
{"label":"{{literal}} {name} {0} {name}"}
target:
{"label":"{0} {name} {{文字}}"}
options:
{"mode":"braces","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[]}二重括弧はリテラルです。両メッセージとも name と 0 を使い、順序や name の反復回数が変わっても引数集合が同じなので不一致にはなりません。
引数名の変更は不一致になる
reference:
{"label":"Hello {name}, item {0}"}
target:
{"label":"{user} さん、項目 {0}"}
options:
{"mode":"braces","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"placeholder-mismatch","path":"/label","side":"after","severity":"error"}]}対象側は位置引数 0 を保持し、name を user に変えています。対象文字列の位置に不一致を報告し、通常の訳文の違いは比較しません。
メッセージ構文エラーも診断可能
reference:
{"label":"Hello {name"}
target:
{"label":"こんにちは {name}"}
options:
{"mode":"braces","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"message-syntax","path":"/label","side":"before","severity":"error"}]}JSON は有効ですが、基準文字列の閉じ括弧がありません。入力を検査できるので valid は true のままでも、message-syntax エラーの修正は必要です。
英語と日本語それぞれのカテゴリー
reference:
{"cart":"{count, plural, one {# item} other {# items}}"}
target:
{"cart":"{count, plural, other {# 個}}"}
options:
{"mode":"icu-flat","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[]}英語には one と other、日本語には other だけがあります。必要な引数と各言語のカテゴリーに合っており、言語間で分岐集合を揃える必要はありません。
網羅不足と到達しない分岐は警告
reference:
{"cart":"{count, plural, other {# items}}"}
target:
{"cart":"{count, plural, one {# 個} other {# 個}}"}
options:
{"mode":"icu-flat","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"category-coverage","path":"/cart","side":"before","severity":"warning"},{"code":"category-unreachable","path":"/cart","side":"after","severity":"warning"}]}英語には明示的な one 分岐がないため網羅性の警告になります。日本語の基数は other を使うのに one を追加しているため、到達しないカテゴリーの警告が出ます。
分岐内の引数と整数セレクター
reference:
{"cart":"{count, plural, =0 {None} one {# {unit}} other {# {unit}}}"}
target:
{"cart":"{count, plural, other {# 個}}"}
options:
{"mode":"icu-flat","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"plural-placeholder-mismatch","path":"/cart","side":"after","severity":"error"},{"code":"branch-placeholder-mismatch","path":"/cart","side":"after","severity":"error"},{"code":"exact-selector-missing","path":"/cart","side":"after","severity":"warning"}]}日本語の other から基準側 other の unit がなくなり、エラーになります。基準側の =0 もなくなっているため別の警告になりますが、これは言語の必須カテゴリーではありません。 全複数形分岐の引数の和集合も比較するため、1 つの引数不足に対して複数形全体と分岐単位の両方のエラーが出る場合があります。
非対応の ICU 構造と other の不足
reference:
{"nested":"{n, plural, one {{m, plural, other {x}}} other {x}}","format":"{price, number}","required":"{n, plural, one {x}}"}
target:
{"nested":"{n, plural, other {#}}","format":"{price}","required":"{n, plural, other {#}}"}
options:
{"mode":"icu-flat","beforeLocale":"en","afterLocale":"ja","arrays":"reject"}{"valid":true,"issues":[{"code":"unsupported-nested","path":"/nested","side":"before","severity":"error"},{"code":"unsupported-formatter","path":"/format","side":"before","severity":"error"},{"code":"missing-other","path":"/required","side":"before","severity":"error"}]}基準側には入れ子の複数形、number フォーマッター、other のない複数形があります。それぞれの文字列パスで診断し、描画・実行・黙認はしません。
国際化レビューでよくある誤り
- i18next 形式の {{name}} をこのツールの波括弧モードで引数と考える。このモードではリテラルです。
- すべての言語に英語と同じ複数形カテゴリーが必要だと考える。
- 点・スラッシュ・チルダを含むキーをドット区切りのパスとして解釈し、JSON Pointer のエスケープを見落とす。
- 要素を並べ替えた配列に索引比較を使う。要素の同一性による対応付けは行いません。
- valid: true をエラーなしと読み違える、または絞り込んだ画面だけが出力されると考える。
- キーパスと引数名の機密性を確認せずにレポートを共有する。訳文を省いても、名前からプロジェクトの情報が分かる場合があります。
制限と注意事項
- ルートがオブジェクトの厳密な JSON のみ対応します。JSONC コメント、末尾カンマ、YAML、JavaScript モジュール、自動修復は対象外です。展開後の重複キーと対にならない Unicode サロゲートを入れ子でも拒否します。オブジェクトのキー順は無視し、大文字小文字を区別して Unicode 正規化はしません。JSON Pointer は ~ を ~0、/ を ~1 にするため、点を含むキーと入れ子を混同しません。__proto__ と constructor は通常のデータキーです。配列は既定で拒否し、明示的に選んだ場合だけ 0 始まりの索引で比較します。空オブジェクト・空配列・null の型は区別します。
- プレーンモードはメッセージ構文を一切検査しません。波括弧モードは {name} や位置引数 {0} に対応し、名前は ASCII [A-Za-z_][A-Za-z0-9_]* または数字のみです。{{ と }} はリテラルの括弧として扱い、単独の不正な括弧はエラーにします。引数集合を比較するため、順序変更と同じ引数の反復は許可します。具体的な値・訳文・引数の出現回数は比較しません。
- ICU-flat は単純な引数、単層の plural と selectordinal、および名前付きカテゴリーか =0 などの非負整数セレクターに対応します。分岐内には単純な引数と # テキストを置けます。入れ子のセレクター、select、number/date などのフォーマッター、offset、同じ引数の複数形定義の繰り返し、ICU のアポストロフィーエスケープは非対応として診断します。各複数形には other が必須です。構文を検査するだけで整形・評価せず、完全な ICU MessageFormat 互換ではありません。 複数形分岐内の # は制御引数の使用と数え、count が制御する場合は {count} と同じ引数として扱います。複数形の外ではリテラルです。 ICU モードの数字の引数名は先頭ゼロのない 0–32767 の整数に限ります。複数形の制御引数名にも適用します。
- 複数形カテゴリーは実行環境の Intl.PluralRules から、各言語と基数・序数の種類ごとに取得します。任意カテゴリーの不足やその言語で到達しないカテゴリーは警告であり、言語間のカテゴリー一致は要求しません。整数セレクターの違いも警告です。対象分岐の引数を基準側の同名セレクターと比べ、なければ基準側の other と比べます。フォールバック・網羅性の確認は静的な近似で、言語としての正しさや描画結果を保証しません。 全複数形分岐の引数の和集合も比較するため、1 つの引数不足に対して複数形全体と分岐単位の両方のエラーが出る場合があります。 =N の完全一致分岐では固定の数値を直接書けるため、その制御引数だけを分岐および和集合の比較から除外し、他の引数は引き続き検査します。
- 各入力は 262,144 UTF-8 バイト、深さ 32、10,000 JSON ノードまでです。1 メッセージの引数・分岐予算は 1,000 トークン、問題は最大 1,000 件、JSON レポートは 1 MiB(1,048,576 バイト)までです。打ち切り・上限超過のレポートは完全版として出力できません。不正な JSON は比較と出力を止めますが、JSON が有効でメッセージに問題がある場合は診断を出力できます。アップロード、ネットワーク照会、永続保存、式の実行は行いません。レポートは訳文を含みませんが、キーパスや引数名自体に機密情報が含まれる可能性があります。 各 JSON Pointer は 4,096 UTF-8 バイト、全パスの合計は 1 MiB までです。診断詳細が 512 UTF-16 コード単位を超えた場合もレポートを打ち切りとして出力を止めます。
よくある質問
訳文や数字が変わっても問題が出ないのはなぜですか?
パス、JSON の型、選択したメッセージ構文を比較します。異なる言語では文章が違うのが通常です。数字と真偽値も型だけを確認し、値を比較・変換しません。具体的な値の差分には JSON Diff を使ってください。
日本語にも英語と同じ複数形の分岐が必要ですか?
不要です。英語と日本語では対応する基数カテゴリーが異なる場合があります。各側の Intl.PluralRules に沿って確認し、other は必須です。任意カテゴリーがない場合は other で処理できるため、網羅性の警告となり、それだけで不正なメッセージとはなりません。
どの引数モードを選べばよいですか?
構文が不明ならプレーンテキストで構造を確認します。波括弧は説明した {name}/{0} と二重括弧によるリテラル表記にだけ使い、ICU-flat も明示した部分集合に限ります。フレームワーク固有の補間、完全な ICU の入れ子、独自フォーマッターは各フレームワークの検証機能が必要です。
検査成功や valid: true は何を意味しますか?
JSON と設定が検査可能という意味で、エラーがないという意味ではありません。問題一覧と重大度を確認してください。問題なしでも、このツールの構造・構文ルールを満たすだけであり、翻訳の正確さ、アプリケーションで使う全キーの網羅、運用環境の言語データとの一致は保証しません。
- RFC 8259:JSON 構文と相互運用性
- RFC 6901:JSON Pointer の位置
- ECMA-402:Intl.PluralRules
- Unicode ICU:MessageFormat と複数形メッセージ
- ICU MessagePattern