localization-engineer について
localization-engineerは、多言語アプリケーション開発向けの国際化スキルです。ロケール検出から翻訳表示までを扱い、ICU、CLDR、RTL、SEOのパターンとParaglide、i18nextの選択指針を紹介します。
主な機能
- 01ロケール検出とネゴシエーションの設定
- 02ICUメッセージとCLDR複数形ルールの利用
- 03日付、数値、リストのローカライズ
- 04RTLレイアウトと多言語SEOへの対応
- 05Paraglideとi18nextの比較
活用シーン
- 01アプリケーションへの多言語対応の追加
- 02ロケールに応じた日付と数値表示の実装
- 03RTLレイアウトと翻訳カバレッジの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ oakoss/ agent-skills --skill localization-engineerインストール後、Claude Code で/localization-engineerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/i18next.mdicu-message-format.mdparaglide.md詳細
ローカライズエンジニア
概要
フレームワークに依存しない、多言語アプリケーションを構築するためのパターンを提供します。ロケールの検出から翻訳のレンダリングまで、i18n パイプライン全体を網羅しています。ICU メッセージの書式設定、CLDR の複数形ルール、RTL サポート、SEO など、共通の課題に対応します。
使用する場面: 多言語対応、ロケールに応じた書式設定、RTL レイアウト、複数形化、翻訳管理、ロケールネゴシエーション、多言語 SEO を導入するとき。
使用しない場面: 国際化の予定がない単一言語のアプリ、ロケールが変わることのないコンテンツ、動的コンテンツのないサーバーレンダリング専用の静的サイト。
主な選択基準: 新規プロジェクトでコンパイル時の型安全性と最小限のバンドルを重視する場合は Paraglide を選びます。既存プロジェクトで幅広いエコシステムのサポートと段階的な導入を重視する場合は i18next を選びます。以下のライブラリ選択表を参照してください。
ライブラリの選択
| 基準 | Paraglide JS | i18next |
|---|---|---|
| アーキテクチャ | コンパイル時、ツリーシェイキング可能な関数 | ランタイム、プラグインベースのエコシステム |
| 型安全性 | 完全(型付きメッセージ関数を生成) | 部分的(手動での型設定が必要) |
| バンドルサイズ | 最小限(使用するメッセージのみを配信) | 大きめのランタイム(ベース約 40 kB + プラグイン) |
| 複数形化 | メッセージフォーマットプラグイン経由 | CLDR の複数形カテゴリーを標準搭載 |
| フレームワーク対応 | SvelteKit、TanStack Start、React Router、Astro、vanilla | React、Vue、Svelte、Angular、Node、vanilla |
| ICU 対応 | inlang-icu-messageformat-1 プラグイン経由 | i18next-icu プラグイン経由 |
| 翻訳ツール | Fink エディター、Sherlock VS Code 拡張機能 | Locize、i18next-parser、多数の連携機能 |
| ロケール戦略 | 標準搭載(cookie、URL、header、custom) | i18next-browser-languagedetector プラグイン経由 |
| SSR 対応 | AsyncLocalStorage ベースのリクエストごとの処理 | リクエストごとに個別の i18next インスタンスを使用 |
| 学習コスト | 低(コンパイラーがシンプルな関数を生成) | 中(API の範囲が広く、多数のプラグインがある) |
| 名前空間のサポート | ロケールごとにフラットなメッセージファイル | ルートごとの遅延読み込みに対応した複数の名前空間 |
| メッセージ形式 | Inlang 形式、またはプラグイン経由の ICU | i18next JSON v4、またはプラグイン経由の ICU |
| コミュニティ規模 | 拡大中(inlang エコシステム) | 大規模(2015 年から確立) |
| 最適な用途 | バンドルサイズと型安全性を重視する新規プロジェクト | 幅広いエコシステムのサポートを必要とする既存プロジェクト |
クイックリファレンス
| パターン | 方法 | 主なポイント |
|---|---|---|
| ICU の複数形 | {count, plural, one {# item} other {# items}} | CLDR のカテゴリー:zero、one、two、few、many、other |
| ICU の選択(性別) | {gender, select, male {He} female {She} other {They}} | 性別に応じたメッセージやバリエーションに対応します |
| ICU の序数選択 | {rank, selectordinal, one {#st} two {#nd} other {#th}} | 序数の接尾辞は言語によって異なります |
| 数値の書式設定 | Intl.NumberFormat(locale, options) | 通貨、パーセント、単位の書式設定がプラットフォームに組み込まれています |
| 日付の書式設定 | Intl.DateTimeFormat(locale, options) | 日付文字列を手作業で構築するのは避けてください |
| 相対時間 | Intl.RelativeTimeFormat(locale, options) | ロケールに応じた出力で「3 時間前」「2 日後」と表示します |
| リストの書式設定 | Intl.ListFormat(locale, { type: 'conjunction' }) | ロケールに応じた接続詞で「Alice、Bob、Charlie」と表示します |
| RTL レイアウト | CSS の論理プロパティ(inline-start、inline-end) | left/right を論理的に対応する値に置き換えます |
| RTL の検出 | <html dir="rtl" lang="ar"> | ロケールに基づいて dir 属性を設定します |
| URL からロケールを取得 | /en/about、/de/about | SEO に最も適しており、ユーザーにも分かりやすい方法です |
| Cookie からロケールを取得 | locale=de cookie | セッションをまたいで設定を保持します |
| ヘッダーからロケールを取得 | Accept-Language: de-DE,de;q=0.9,en;q=0.8 | ブラウザーの設定を使い、フォールバックとして利用します |
| Hreflang タグ | <link rel="alternate" hreflang="de" href="..."> | x-default に加えて、ロケールごとに 1 つ設定します |
| 名前空間の分割 | 機能またはルートごとに翻訳をグループ化します | 遅延読み込みによりバンドルサイズを削減します |
| メッセージの抽出 | 自動化ツールでソースをスキャンし、翻訳キーを検出します | 孤立した翻訳や不足している翻訳を防ぎます |
| 擬似ローカライズ | レイアウトのテスト用に、擬似的な翻訳を生成します | 途中で切れるテキスト、オーバーフロー、ハードコードされた文字列を検出します |
よくある間違い
| 間違い | 正しい方法 |
|---|---|
| 翻訳した断片を連結して文章を作る | 各ロケールで適切な文法を保つため、プレースホルダーを使った ICU メッセージ形式を使用する |
RTL で margin-left/padding-right を使う | CSS の論理プロパティ(margin-inline-start、padding-inline-end)を使用する |
複数形のルールをハードコードする(count === 1) | CLDR の複数形カテゴリを使用する(言語によってはゼロ、2、少数、多数の形があります) |
| IP ジオロケーションだけでロケールを判定する | Accept-Language ヘッダー、Cookie、最後の手段としてジオロケーションを使用する |
hreflang タグに x-default がない | フォールバック用に <link rel="alternate" hreflang="x-default"> を必ず含める |
| ロケールごとに巨大な翻訳ファイルを1つ作る | 遅延読み込みと保守性のため、機能ごとに名前空間へ分割する |
| コンポーネントごとに新しい i18next インスタンスを作成する | アプリの初期化時に一度だけ作成し、コンポーネント間で共有する |
| 文字列を連結して日付をフォーマットする | ロケールに応じた日付表示には Intl.DateTimeFormat を使用する |
| コンポーネントの状態にロケールを保存する | SSR との互換性と共有のしやすさのため、URL パスまたは Cookie に保存する |
| クライアントとサーバーで異なる i18n キーを使用する | クライアントとサーバーで翻訳ファイルとキー構造を共有する |
| すべての言語で同じ程度に文字列が長くなると想定する | 英語と比べて、ドイツ語/フィンランド語の翻訳用に30〜40%余分なスペースを確保する |
| 画像にテキストを埋め込む | 翻訳を動的に適用できるよう、CSS/SVG のテキストオーバーレイを使用する |
| 地域別のバリエーションなしで言語コードを使う | 日付や通貨などの書式に違いがある場合は、en-US と en-GB を使い分ける |
委任
- コードベース内のハードコードされた文字列を監査する:
Exploreエージェントを使って、翻訳されていないユーザー向けテキストがないかコンポーネントをスキャンします - 完全な i18n パイプラインを設定する:
Taskエージェントを使って、ロケールの判定、翻訳の読み込み、レンダリングを設定します - ローカライズのアーキテクチャを計画する:
Planエージェントを使って、名前空間の構造、ロケール戦略、翻訳ワークフローを設計します - 翻訳の網羅状況を確認する:
Taskエージェントを使って翻訳ファイルを比較し、ロケール間の不足キーを特定します - i18n 準拠のコードレビュー:
code-reviewerエージェントに委任します
tanstack-startスキルが利用可能な場合は、サーバーミドルウェアと SSR のロケールパターンを委任します。tanstack-routerスキルが利用可能な場合は、URL ベースのロケールルーティングパターンを委任します。sveltekitスキルが利用可能な場合は、SvelteKit 固有のルーティングとフックのパターンを委任します。seoスキルが利用可能な場合は、高度な hreflang とサイトマップのパターンを委任します。
参考資料
- Paraglide JS のパターン -- 型付きメッセージ関数を使ったコンパイル時 i18n、SvelteKit/TanStack Start/React Router との統合、ロケール戦略
- i18next のパターン -- プラグインエコシステムを使った実行時 i18n、React/Vue/Svelte/バニラ JS との統合、名前空間、言語判定
- ICU メッセージ形式 -- 複数形、select、数値/日付の書式設定、ネストされたメッセージ、RTL サポート、hreflang SEO