モバイルアプリのローカライズ

更新日:6 日前 · 読了目安 2分

Lingo.dev CLI は、設定した .stringsローカライゼーションエンジン を通じて、Xcode 、Android XML、Flutter ARB、React Native JSON などのネイティブモバイル向けリソースファイルを翻訳します。CLI は拡張子から各ファイル形式を自動判別し、構造を保ったまま、複数形にもネイティブ対応します。

プラットフォーム概要#

プラットフォームネイティブ形式一般的なソースファイルパス
iOS(Xcode).stringsen.lproj/Localizable.strings
iOS(Xcode).stringsdicten.lproj/Localizable.stringsdict
iOS(Xcode).xcstringsLocalizable.xcstrings
Androidstrings.xmlapp/src/main/res/values/strings.xml
Flutter.arblib/l10n/app_en.arb
React Native.jsonsrc/locales/en.json

前提条件#

CLI を実行するたびに、コンテンツは ローカライゼーションエンジン を通ります。これは、適用する LLM モデル、用語集、ブランドボイス、ルールを決める設定です。Lingo.dev のダッシュボードで作成できます。

CLI(Node.js 22+)をインストールして認証します。

bash
npm install -g @lingo.dev/cli
lingo login

lingo login を実行すると、ワンタイムコードでサインインできます。CI では対話型ログインを使わず、--api-key を渡してください(または LINGO_API_KEY を設定してください)。

プラットフォームの設定#

lingo init を実行して .lingo/config.json(source/target ロケールとファイルパターン)を作成し、続けて lingo link で orgId と engineId を関連付けます。.lingo/config.json をリポジトリにコミットしてください。以下の例では、各プラットフォームで最終的に生成される設定を示しています。

パターンは常に source ファイルを指し、CLI はそこから各ターゲットのパスを導き出します。通常は、パス内で見つかったロケールを置き換えるだけです(en.lproj → de.lproj、app_en.arb → app_de.arb)。ただし、2 つのプラットフォームだけは例外で、どちらも自動で処理されます。String Catalog ではすべてのロケールを 1 つのファイルにまとめるため、ターゲットパスはソースパスと同じです。Android では、デフォルト文字列はパスにロケールを含まない修飾子なしの values/ に置かれるため、CLI がそこにターゲット修飾子を付け加えます(values/ → values-de/)。

Xcode は 3 つのローカライズ形式に対応しています。プロジェクト構成に合ったものを選んでください。

String Catalogs (.xcstrings) - Xcode 15 で導入された最新の Xcode 形式です。1 つの JSON ファイルにすべてのロケールがまとまり、新しい文字列を追加すると Xcode が自動で更新します。CLI はこのファイルをその場で更新するため、パターンはロケールセグメントのない単一のカタログを指します。

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de", "ja"],
  "files": [{ "pattern": "MyApp/Localizable.xcstrings" }]
}

従来の .strings ファイル - [code].lproj/ ディレクトリごとに、ロケール単位で 1 ファイルずつ配置されます。ソースロケールはパス内に含まれ(en.lproj)、CLI は各ターゲットをそれぞれの .lproj ディレクトリに書き込みます。プロジェクトで複数形用に .stringsdict も使っている場合は、2 つ目の files エントリを追加してください。

json
{
  "orgId": "org_...",
  "engineId": "eng_...",
  "sourceLocale": "en",
  "targetLocales": ["es", "fr", "de", "ja"],
  "files": [
    { "pattern": "MyApp/en.lproj/Localizable.strings" },
    { "pattern": "MyApp/en.lproj/Localizable.stringsdict" }
  ]
}

開発言語バンドルが Base.lproj で、en.lproj ではないプロジェクトでも問題ありません。CLI は Base.lproj を source ロケールとして認識します。

Xcode の i18n 基盤の設定方法については、Apple のローカライズ関連ドキュメントをご覧ください。

翻訳の実行#

1 つのコマンドですべてのリソースファイルを翻訳できます。

bash
lingo push --wait

CLI はソースロケールファイルを読み込み、lockfile(コミット対象の .lingo/lock.json)を使って前回の実行以降の変更点を計算し、差分だけを翻訳してターゲットロケールファイルに書き込みます。

初回実行時、または新しいターゲットロケールを追加したときは、すべてをゼロから翻訳します。

bash
lingo push --backfill-missing --wait

プロジェクトに複数のリソースタイプが含まれている場合は、glob を渡して対象のプラットフォームを絞り込みます(--bucket や --target-locale のようなフラグはありません)。パターンは source パスに対して照合されるため、ターゲットではなく source ファイルを基準に範囲を指定してください。

bash
lingo push "app/src/main/res/values/strings.xml"
lingo push "MyApp/Localizable.xcstrings"

このチェックアウトから送信された最新の実行結果を収集するには、lingo pullを実行してください。ほかのマシンでは、翻訳はコミットされると取り込まれます。変更を書き込まずに翻訳が最新かどうかを確認するには――デプロイ前の確認にも便利です――lingo checkを実行してください。

複数形とプラットフォームごとの慣習#

複数形の扱いはモバイルプラットフォームごとに異なります。iOS は .stringsdict または String Catalog のルール、Android は <plurals> XML 要素、Flutter は ARB ファイル内の ICU MessageFormat を使います。CLI は翻訳時に各プラットフォーム固有の複数形構造を保持し、各ターゲットロケールに対して正しい複数形カテゴリを生成します。

翻訳者向けメモ

モバイル向けの文字列は短く、文脈に左右されやすい傾向があります。文字列がどこに表示されるかという文脈をローカライゼーションエンジンに伝えるために、Xcode の ファイルで .xcstringstranslator notes を使ってください。たとえば、"checkout フローのボタンラベル" と "ナビゲーションメニューの項目" では、適切な訳し方が異なります。

CI で自動化する#

翻訳を常に最新に保つための推奨方法は、Lingo.dev GitHub App を使うことです。これはサーバー側で動作し、コミット済みの .lingo/config.json と engineId を読み取って、翻訳更新を自動で作成します。runner、secret、lockfile を自分で管理する必要はありません。独自のパイプラインで翻訳を実行したい場合は、CI runner 上で lingo push を実行し、結果をコミットしてください。

プラットフォーム別ガイド#

次のステップ#