Lingo.dev CLI は、設定した ローカライゼーションエンジン を通じて、Android の strings.xml文字列リソース()を翻訳します。android 形式では、CLI が <resources>、<string>、<string-array>、<plurals> 要素をネイティブに理解するため、XML 構造を保ったまま、各ターゲットロケールに適した複数形カテゴリを正しく生成できます。
このガイドでは、CLI の設定、ローカルでの翻訳、CI での自動化まで、Android アプリのローカライズを一通り紹介します。push のたびに翻訳を反映した状態でリリースできるようになります。
デモリポジトリ
一緒に進めるには、lingodotdev/android-app-localization-example を clone または fork してください。このリポジトリには、文字列リソース、Lingo.dev CLI の設定、そして各ターゲット ロケール向けの翻訳がコミット済みの、すぐに動かせる Android プロジェクトが含まれています。
Android ローカライゼーションの仕組み#
Android では、各ロケールごとに専用の ディレクトリを用意する values-[locale]/リソースディレクトリの規約 が使われます。システムは、デバイスの言語設定に応じて、実行時に適切な strings.xml を読み込みます。
app/src/main/res/
values/ # Default (source) strings
strings.xml
values-es/ # Spanish
strings.xml
values-fr/ # French
strings.xml
values-ja/ # Japanese
strings.xml一般的な strings.xml には、次の 3 種類の要素があります。
<resources>
<!-- Simple strings -->
<string name="app_name">My App</string>
<string name="welcome_message">Welcome back!</string>
<!-- String arrays -->
<string-array name="planets">
<item>Mercury</item>
<item>Venus</item>
<item>Earth</item>
</string-array>
<!-- Plurals -->
<plurals name="items_count">
<item quantity="one">%d item</item>
<item quantity="other">%d items</item>
</plurals>
</resources>CLI はこれら 3 種類すべての要素を解析し、ローカライゼーションエンジンを通じて翻訳したうえで、ロケールごとのファイルを適切な values-[locale]/ ディレクトリに書き出します。
前提条件#
ローカライゼーションエンジンを作成する
CLI を実行するたびに、コンテンツは ローカライゼーションエンジン を通ります。これは、どの LLM モデル、glossary、ブランドボイス、rules を適用するかを決める設定です。作成は Lingo.dev dashboard から行えます。
Node.js を確認する
CLI の利用には Node.js 22 以上が必要です:
node -vCLI をインストール
CLI をグローバルインストールすると、lingo コマンドが使えるようになります:
npm install -g @lingo.dev/cliサインイン
Android プロジェクトを準備する
プロジェクトには、strings.xml 内にデフォルトの app/src/main/res/values/ が必要です。Android Studio では、新規プロジェクトを作成するとこのファイルが自動で作成されます。リソースディレクトリの設定方法については、Android の localization guide を参照してください。
CLI を設定する#
プロジェクトルートで lingo init を実行し、ソースロケール、ターゲットロケール、ファイルパターンを含む .lingo/config.json を作成します。続けて lingo link を実行して、組織とエンジンを紐付けます。結果は次のようになります:
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
}
]
}このパターンは、デフォルトのリソース ディレクトリ、つまり Android がソース文字列の配置先として想定している修飾子なしの values/ を指します。ここにロケール コードは含まれず、その必要もありません。
`format` を明示的に設定する理由
CLI はほとんどの形式をファイル拡張子から自動判別しますが、.xml は判別が難しいため、Android リソースファイルでは files エントリに "format": "android" を明示的に指定する必要があります。
複数のリソースファイル
プロジェクト内で文字列を複数のファイル(たとえば strings.xml や arrays.xml)に分けている場合は、それぞれに files エントリを追加してください。
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
},
{
"pattern": "app/src/main/res/values/arrays.xml",
"format": "android"
}
]
}.lingo/config.json はリポジトリにコミットしてください。
ロケール ディレクトリと修飾子#
Android では、デフォルト言語は修飾子なしの values/ ディレクトリに置かれるため、ソース パスにロケール コードは入りません。CLI もこれを理解しており、修飾子のない values/ をソース ロケールとして扱い、それ以外のロケールにはターゲット修飾子を付け加えます。
| ロケール | リソース ディレクトリ |
|---|---|
en(ソース) | values/ |
es | values-es/ |
pt-BR | values-pt-rBR/ |
zh-Hans | values-b+zh+Hans/ |
地域付きロケールやスクリプト付きロケールは、ここで押さえておく価値があります。というのも、リソース修飾子は BCP 47 タグをそのまま使うわけではないからです。Android が受け付ける表記は 2 つあります。従来の言語-地域形式(values-pt-rBR/)と、b+ を接頭辞に付けた BCP 47 形式(values-b+pt+BR/、API 24 以降)です。values-pt-BR/ という名前のディレクトリは完全に無視されるため、文字列が存在していても読み込まれません。
"format": "android" を設定しておけば、CLI が適切な表記を自動で出力してくれます。ロケールを表現できる場合は従来形式を使い、スクリプト、3 文字の言語コード、数値の地域コードには b+ を使います。
古いセットアップから移行する場合
以前の CLI バージョンでは、ソース パスにロケールを含める必要があり、このガイドでも 2 つの方式をつなぐために values-en -> values のシンボリックリンクを推奨していました。@lingo.dev/cli 1.12.0 以降はもう不要です。パターンを values/strings.xml に向け、シンボリックリンクは削除してください。
ローカルで翻訳する#
CLI を実行します。初回実行時、または新しいターゲットロケールを追加したときは、既存のすべての文字列を翻訳するために --backfill-missing を使ってください:
lingo push --backfill-missingCLI はソースの strings.xml を読み取り、run state を使って未翻訳のエントリを特定し、その差分をローカライゼーションエンジン経由で翻訳して、結果をターゲットの values-[locale]/ ディレクトリに書き込みます。翻訳された文字列を確認するには、任意のターゲットファイルを開いてください。
2回目以降の実行では、lingo push は変更された内容だけを翻訳します:
lingo push実行対象を特定のファイルに絞るには、glob を渡します。パターンはソース パスに対して照合されるため、ターゲットではなくソース ファイル単位でスコープを指定してください。
lingo push "app/src/main/res/values/strings.xml"別の場所(たとえば CI)で生成された翻訳を作業ツリーに取り込むには、lingo pull を実行します。
複数形#
Android では、複数形を扱うために <plurals> 要素と CLDR quantity strings(zero、one、two、few、many、other)を使います。必要な複数形カテゴリは言語によって異なり、英語では 2 つ(one と other)、ロシア語では 4 つ、アラビア語では 6 つ必要です。
CLI は翻訳時も <plurals> の構造を保ち、各ターゲットロケールに適した quantity エントリを生成します。たとえば、2 つのカテゴリを持つソースエントリがあると、
<plurals name="messages_count">
<item quantity="one">%d new message</item>
<item quantity="other">%d new messages</item>
</plurals>各ターゲット言語に対して正しいカテゴリが生成されます。ローカライゼーションエンジンは、各ロケールに適用される CLDR plural rules を理解しており、その言語に必要なカテゴリだけを生成します。
キーのロック#
ブランド名や API エンドポイント、書式パターンなど、一部の文字列値はすべての言語で同一のままにしたいことがあります。そうした場合は キーのロック を使うことで、翻訳せずに値をそのままコピーできます。
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android",
"lockedKeys": ["app_name", "api_base_url"]
}
]
}ロックされたキーは翻訳パイプラインを通さず、ソースからすべてのターゲットファイルへそのままコピーされます。
CI で自動化#
翻訳を常に最新に保つおすすめの方法は、Lingo.dev GitHub App です。サーバー側で動作し、コミット済みの .lingo/config.json と engineId を読み取って、翻訳の更新を自動で作成します。ランナー不要、シークレットの保存不要、さらに lockfile の管理も不要です。インストールしてリポジトリを指定すれば、push のたびに翻訳が実行されます。
CLI を自前のパイプライン内で実行したい場合は、CLI をインストールして lingo push を実行するワークフローを追加してください:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm install -g @lingo.dev/cli
- run: lingo push --backfill-missing
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}API キーは、GitHub リポジトリの Settings > Secrets and variables > Actions で LINGO_API_KEY として保存し、その後のステップで更新されたターゲットファイルをコミットするか、プルリクエストを作成してください。
デプロイ前に検証する#
未翻訳の文字列が本番環境に出ないよう、lingo check をデプロイゲートとして活用してください。翻訳が必要なエントリが1つでもある場合、このコマンドは非ゼロステータスで終了します:
lingo checkこれをビルド前の独立した CI ステップとして追加してください。
- name: Verify translations
run: lingo check
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}