CLI はモノレポをネイティブサポートしています。ルートに 1 つの i18n.json を置いて再帰的な ** glob でパッケージを自動検出する方法、パッケージごとのパスを明示した単一のルート設定を使う方法、あるいは各パッケージに個別の i18n.json ファイルを置き、matrix strategy の GitHub Action と組み合わせる方法があります。
各パターンを使い分ける目安#
| シナリオ | パターン | 設定ファイル | GitHub Action |
|---|---|---|---|
| すべてのパッケージでレイアウトとロケールが共通で、新しいパッケージも自動で取り込みたい | 再帰的な単一設定 | ルートに 1 つの i18n.json と ** glob | 1 ステップ、デフォルトの working-directory |
| すべてのパッケージでソースロケールとターゲットロケールを共有する | 単一設定 | ルートに 1 つの i18n.json | 1 ステップ、デフォルトの working-directory |
| パッケージごとに異なるターゲットロケールが必要 | パッケージごとの設定 | 各パッケージに 1 つずつ i18n.json | working-directory を使った matrix strategy |
| パッケージごとに異なるエンジン(用語集、ブランドボイス)が必要 | パッケージごとの設定 + 個別エンジン | 各パッケージに 1 つずつ i18n.json を置き、それぞれに専用の engineId を設定 | working-directory を使った matrix strategy |
パターン 1: 再帰的な単一設定#
すべてのパッケージが同じレイアウト(例: apps/<name>/locales/[locale].json)に従っているなら、ルートの 1 つの i18n.json で再帰的な ** glob を使います。レイアウトに一致していれば、新しいパッケージも自動で取り込まれます。
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja"]
},
"buckets": {
"json": {
"include": ["apps/**/locales/[locale].json"]
}
}
}CLI はデフォルトで node_modules、.git、dist、build、.next、.turbo を無視するため、再帰パターンが vendored や build のツリーまで入り込むことはありません。ほかにも除外したいものがあれば、独自の exclude エントリを追加してください。
GitHub Action は下のパターン 2 と同じで、1 ステップ・デフォルトの working directory で実行できます。
すべてのパッケージでソースロケール、ターゲットロケール、レイアウト、ローカライゼーションエンジンが共通していて、パッケージを追加するたびに i18n.json を編集したくない場合に適しています。
パターン 2: 単一設定、共有ロケール#
リポジトリのルートに 1 つの i18n.json を配置し、bucket paths で各パッケージへのパスを明示的に指定します。
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja"]
},
"buckets": {
"json": {
"include": [
"apps/web/locales/[locale].json",
"apps/dashboard/locales/[locale].json"
]
},
"markdown": {
"include": ["packages/docs/content/[locale]/*.md"]
}
}
}GitHub Action – 標準的な 1 ステップ構成:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
pull-request: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}すべてのパッケージでソースロケール、ターゲットロケール、ローカライゼーションエンジンは共通だが、レイアウトの違いが大きく、再帰的な glob では対象が広がりすぎる場合に適しています。
パターン 3: パッケージごとの設定、異なるロケール#
各パッケージは、それぞれ独立したターゲットロケールを持つ独自の i18n.json を持ちます。
apps/web/i18n.json:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja", "ko", "zh-Hans"]
},
"buckets": {
"json": {
"include": ["locales/[locale].json"]
}
}
}apps/marketing/i18n.json:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de"]
},
"buckets": {
"json": {
"include": ["locales/[locale].json"]
},
"markdown": {
"include": ["content/[locale]/*.md"]
}
}
}GitHub Action – working-directory を使った matrix strategy:
name: Translate
on:
push:
branches: [main]
permissions:
contents: write
pull-requests: write
jobs:
translate:
runs-on: ubuntu-latest
strategy:
matrix:
package: [apps/web, apps/marketing]
steps:
- uses: actions/checkout@v4
- uses: lingodotdev/lingo.dev@main
with:
api-key: ${{ secrets.LINGODOTDEV_API_KEY }}
working-directory: ${{ matrix.package }}
pull-request: true
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}各 matrix エントリは、そのパッケージの i18n.json を対象に CLI を実行します。action が翻訳するのは、そのパッケージで宣言されたファイルだけです。
パターン 4: パッケージごとの設定、個別のエンジン#
構成はパターン 3 と同じですが、各パッケージは異なるローカライゼーションエンジンに接続します。これにより、各パッケージごとに専用の用語集、ブランドボイス、モデル設定を持てます。
apps/product/i18n.json:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr", "de", "ja"]
},
"buckets": {
"json": {
"include": ["locales/[locale].json"]
}
},
"engineId": "eng_ProductApp123"
}apps/docs/i18n.json:
{
"$schema": "https://lingo.dev/schema/i18n.json",
"version": "1.15",
"locale": {
"source": "en",
"targets": ["es", "fr"]
},
"buckets": {
"markdown": {
"include": ["content/[locale]/*.md"]
}
},
"engineId": "eng_DocsEngine456"
}GitHub Action の YAML はパターン 3 と同じです。各 i18n.json 内の engineId が、翻訳を自動的に正しいエンジンへ振り分けます。
lockfile の仕組み#
各 i18n.json の場所ごとに、同じディレクトリ内へ対応する i18n.lock ファイルが生成されます。lockfile は、どのソースコンテンツが翻訳済みかを追跡し、増分更新を可能にします。パターン 1 と 2 ではルートに 1 つの lockfile、パターン 3 と 4 では各パッケージにそれぞれ lockfile があります。
FAQ#
新しいパッケージも自動で取り込まれますか?
自動で取り込まれるのはパターン 1(再帰的な **)だけです。パターン 3 と 4 では、パッケージを追加したら workflow の matrix.package リストにも新しいエントリを追加します。
パッケージごとに異なるロケールを設定できますか?
はい。パターン 3 または 4 を使ってください。各パッケージの i18n.json で、それぞれ独立した locale.targets 配列を宣言できます。
workflow ファイルは 1 つで十分ですか?それとも複数必要ですか?
matrix strategy を使った 1 つの workflow ファイルで、すべてのパッケージを扱えます。各 matrix エントリは異なる working-directory に対して実行されるため、CLI はそのパッケージの設定にスコープされます。
用語集を共有しつつ、パッケージごとにロケールを変えられますか?
はい。両方のパッケージを同じ engineId に向けつつ、それぞれの i18n.json で異なる locale.targets を設定してください。エンジンの用語集は、指定されたどのロケールペアにも適用されます。
