A CLI da Lingo.dev traduz recursos de string do Android (strings.xml) por meio de um engine de localização configurado. Com o formato android, a CLI entende nativamente os elementos <resources>, <string>, <string-array> e <plurals>, preserva a estrutura do XML e gera as categorias de plural corretas para cada idioma de destino.
Este guia mostra como localizar um app Android de ponta a ponta: configurar a CLI, traduzir localmente e automatizar no CI para que as traduções sejam entregues a cada push.
Repositório de demonstração
Faça um clone ou fork de lingodotdev/android-app-localization-example para acompanhar. O repositório traz um projeto Android funcional com recursos de string, uma configuração do Lingo.dev CLI e traduções versionadas para cada idioma de destino.
Como funciona a localização no Android#
O Android usa uma convenção de diretórios de recursos em que cada idioma tem seu próprio diretório values-[locale]/. Em tempo de execução, o sistema carrega o strings.xml correto com base na configuração de idioma do dispositivo.
app/src/main/res/
values/ # Default (source) strings
strings.xml
values-es/ # Spanish
strings.xml
values-fr/ # French
strings.xml
values-ja/ # Japanese
strings.xmlUm strings.xml típico contém três tipos de elementos:
<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>A CLI analisa os três tipos de elementos, traduz o conteúdo por meio do engine de localização e grava arquivos por idioma nos diretórios values-[locale]/ corretos.
Pré-requisitos#
Crie um engine de localização
Cada execução do CLI envia o conteúdo por um engine de localização — a configuração que define qual modelo de LLM, glossário, voz da marca e regras serão aplicados. Crie um no painel da Lingo.dev.
Verifique o Node.js
A CLI requer Node.js 22 ou superior:
node -vInstale a CLI
Instale a CLI globalmente, o que disponibiliza o comando lingo:
npm install -g @lingo.dev/cliFaça login
Autentique-se com uma senha de uso único:
lingo loginPara CI, use uma chave de API — passe --api-key ou defina LINGO_API_KEY.
Configure seu projeto Android
Seu projeto precisa de um strings.xml padrão em app/src/main/res/values/. O Android Studio cria esse arquivo quando você inicia um novo projeto. Consulte o guia de localização do Android para configurar os diretórios de recursos.
Configure a CLI#
Execute lingo init na raiz do projeto para criar .lingo/config.json com seus idiomas de origem e destino e os padrões de arquivo; depois, execute lingo link para vincular sua organização e seu engine. O resultado fica assim:
{
"orgId": "org_...",
"engineId": "eng_...",
"sourceLocale": "en",
"targetLocales": ["es", "fr", "de", "ja"],
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
}
]
}O padrão aponta para o diretório de recursos padrão — o values/ sem qualificador, exatamente onde o Android espera encontrar as strings de origem. Nenhum código de idioma aparece ali, nem precisa aparecer.
Por que `format` é definido explicitamente
A CLI detecta automaticamente a maioria dos formatos pela extensão do arquivo, mas .xml é ambíguo. Por isso, arquivos de recurso do Android precisam de um "format": "android" explícito na entrada files.
Vários arquivos de recursos
Se o seu projeto distribui as strings em vários arquivos (por exemplo, strings.xml e arrays.xml), adicione uma entrada em files para cada um:
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android"
},
{
"pattern": "app/src/main/res/values/arrays.xml",
"format": "android"
}
]
}Faça commit de .lingo/config.json no repositório.
Diretórios de idioma e qualificadores#
No Android, o idioma padrão fica em um diretório values/ sem qualificador, então o caminho de origem não leva código de idioma. O CLI entende isso: trata values/ sem qualificador como o idioma de origem e acrescenta o qualificador de destino para cada um dos demais idiomas.
| idioma | Diretório de recursos |
|---|---|
en (origem) | values/ |
es | values-es/ |
pt-BR | values-pt-rBR/ |
zh-Hans | values-b+zh+Hans/ |
Vale a pena entender como funcionam idiomas regionais e com script aqui, porque um qualificador de recurso não é uma tag BCP 47 pura. O Android aceita duas grafias: a forma legada idioma-região (values-pt-rBR/) e uma forma BCP 47 com o prefixo b+ (values-b+pt+BR/, API 24 ou superior). Um diretório chamado values-pt-BR/ é simplesmente ignorado — as strings até podem existir, mas nunca serão carregadas.
Ao definir "format": "android", o CLI gera a grafia correta para você: a forma legada sempre que ela conseguir representar o idioma e b+ para scripts, idiomas de três letras e regiões numéricas.
Migrando de uma configuração antiga
As versões anteriores do CLI exigiam que o idioma aparecesse no caminho de origem, e este guia costumava recomendar um symlink values-en -> values para fazer a ponte entre as duas convenções. A partir do @lingo.dev/cli 1.12.0, isso não é mais necessário — aponte o padrão para values/strings.xml e remova o symlink.
Traduza localmente#
Execute a CLI. Na primeira execução — ou sempre que você adicionar um novo idioma de destino — use --backfill-missing para que todas as strings existentes sejam traduzidas:
lingo push --backfill-missingA CLI lê seu strings.xml de origem, identifica as entradas não traduzidas usando o estado da execução, traduz o delta por meio do seu engine de localização e grava os resultados nos diretórios values-[locale]/ de destino. Abra qualquer arquivo de destino para ver as strings traduzidas.
Nas execuções seguintes, lingo push traduz apenas o que mudou:
lingo pushPara limitar uma execução a arquivos específicos, passe um glob. Os padrões são comparados com os caminhos de origem, então restrinja pelo arquivo de origem, não por um destino:
lingo push "app/src/main/res/values/strings.xml"Para trazer para sua árvore de trabalho traduções geradas em outro lugar (por exemplo, no CI), execute lingo pull.
Plurais#
O Android usa elementos <plurals> com strings de quantidade do CLDR (zero, one, two, few, many, other) para lidar com formas de plural. Idiomas diferentes exigem categorias de plural diferentes — o inglês precisa de duas (one e other), o russo precisa de quatro e o árabe precisa de seis.
A CLI preserva a estrutura de <plurals> durante a tradução e gera as entradas de quantidade corretas para cada idioma de destino. Uma entrada de origem com duas categorias:
<plurals name="messages_count">
<item quantity="one">%d new message</item>
<item quantity="other">%d new messages</item>
</plurals>Gera as categorias corretas para cada idioma de destino. O engine de localização sabe quais regras de plural do CLDR se aplicam a cada idioma e gera apenas as categorias exigidas por aquela língua.
Bloqueio de chaves#
Alguns valores de string precisam permanecer idênticos em todos os idiomas — nomes de marca, endpoints de API ou padrões de formatação. Use o bloqueio de chaves para copiar esses valores sem traduzi-los:
{
"files": [
{
"pattern": "app/src/main/res/values/strings.xml",
"format": "android",
"lockedKeys": ["app_name", "api_base_url"]
}
]
}As chaves bloqueadas são copiadas da origem para todos os arquivos de destino sem passar pelo pipeline de tradução.
Automatize no CI#
A forma recomendada de manter as traduções em dia é com o Lingo.dev GitHub App. Ele roda no servidor, lê seus arquivos versionados .lingo/config.json e engineId e abre atualizações de tradução automaticamente — sem runner, sem segredos armazenados e sem gerenciamento de lockfile da sua parte. Instale-o e aponte-o para o seu repositório para traduzir a cada push.
Se você preferir executar a CLI no seu próprio pipeline, adicione um workflow que instale a CLI e execute 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 }}Armazene sua chave de API como LINGO_API_KEY em Settings > Secrets and variables > Actions no repositório do GitHub e, em seguida, faça commit dos arquivos de destino atualizados (ou abra um pull request) como etapa seguinte.
Verifique antes de implantar#
Use lingo check como gate de deploy para garantir que nenhuma string sem tradução chegue à produção. O comando retorna um status diferente de zero se alguma entrada precisar de tradução:
lingo checkAdicione isso como uma etapa separada de CI antes do build:
- name: Verify translations
run: lingo check
env:
LINGO_API_KEY: ${{ secrets.LINGO_API_KEY }}