A CLI oferece suporte nativo a monorepos. Use um único i18n.json na raiz com um glob recursivo ** para detectar pacotes automaticamente, uma única configuração na raiz com caminhos explícitos por pacote ou arquivos i18n.json separados em cada pacote, combinados com uma GitHub Action com estratégia de matriz.
Quando usar cada padrão#
| Cenário | Padrão | Arquivos de configuração | GitHub Action |
|---|---|---|---|
| Todos os pacotes compartilham o mesmo layout e os mesmos idiomas, e você quer que novos pacotes sejam detectados automaticamente | Configuração única recursiva | Um i18n.json na raiz com um glob ** | Uma etapa, working-directory padrão |
| Todos os pacotes compartilham os idiomas de origem e de destino | Configuração única | Um i18n.json na raiz | Uma etapa, working-directory padrão |
| Os pacotes precisam de idiomas de destino diferentes | Configurações por pacote | Um i18n.json por pacote | Estratégia de matriz com working-directory |
| Os pacotes precisam de engines diferentes (glossário, voz da marca) | Configurações por pacote + engines separados | Um i18n.json por pacote, cada um com seu próprio engineId | Estratégia de matriz com working-directory |
Padrão 1: Configuração única recursiva#
Quando todos os pacotes seguem o mesmo layout (por exemplo, apps/<name>/locales/[locale].json), use um glob recursivo ** em um único i18n.json na raiz. Novos pacotes são detectados automaticamente, desde que sigam esse layout:
{
"$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"]
}
}
}A CLI ignora node_modules, .git, dist, build, .next e .turbo por padrão, então padrões recursivos não entram em árvores vendorizadas ou de build. Adicione suas próprias entradas exclude para qualquer outra coisa que você queira ignorar.
A GitHub Action é idêntica à do Padrão 2 abaixo: uma etapa, diretório de trabalho padrão.
Use este padrão quando todos os pacotes compartilharem o mesmo idioma de origem, os mesmos idiomas de destino, o mesmo layout e o mesmo engine de localização, e você não quiser editar i18n.json toda vez que adicionar um pacote.
Padrão 2: Configuração única, idiomas compartilhados#
Um i18n.json na raiz do repositório. Os caminhos dos buckets apontam explicitamente para cada pacote:
{
"$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 — etapa única padrão:
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 }}Use este padrão quando todos os pacotes compartilharem o mesmo idioma de origem, os mesmos idiomas de destino e o mesmo engine de localização, mas os layouts forem diferentes o bastante para que um glob recursivo fique amplo demais.
Padrão 3: Configurações por pacote, idiomas diferentes#
Cada pacote tem seu próprio i18n.json com idiomas de destino independentes:
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 — estratégia de matriz com working-directory:
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 }}Cada entrada da matriz executa a CLI com escopo no i18n.json daquele pacote. A action traduz apenas os arquivos declarados por aquele pacote.
Padrão 4: Configurações por pacote, engines separados#
A estrutura é a mesma do Padrão 3, mas cada pacote se conecta a um engine de localização diferente. Assim, cada pacote tem seu próprio glossário, sua própria voz da marca e sua própria configuração de modelo.
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"
}O YAML da GitHub Action é idêntico ao do Padrão 3: o engineId em cada i18n.json direciona as traduções automaticamente para o engine correto.
Como o lockfile funciona#
Cada localização de i18n.json gera seu próprio arquivo i18n.lock no mesmo diretório. O lockfile rastreia qual conteúdo de origem foi traduzido, permitindo atualizações incrementais. Nos Padrões 1 e 2, há um lockfile na raiz. Nos Padrões 3 e 4, cada pacote tem seu próprio lockfile.
FAQ#
Novos pacotes serão detectados automaticamente?
Somente com o Padrão 1 (recursivo **). Nos Padrões 3 e 4, você adiciona uma nova entrada à lista matrix.package do workflow quando adiciona um pacote.
Posso ter idiomas diferentes por pacote?
Sim. Use o Padrão 3 ou 4. O i18n.json de cada pacote declara seu próprio array locale.targets de forma independente.
Preciso de um arquivo de workflow ou de vários?
Um único arquivo de workflow com estratégia de matriz dá conta de todos os pacotes. Cada entrada da matriz é executada com um working-directory diferente, limitando a CLI à configuração daquele pacote.
Os pacotes podem compartilhar um glossário, mas ter idiomas diferentes?
Sim. Aponte os dois pacotes para o mesmo engineId, mas configure locale.targets diferentes em cada i18n.json. O glossário do engine se aplica a quaisquer pares de idiomas solicitados.
