Guias
Trabalhar com tradutores
Seus catálogos são JSON plano, sem nada proprietário para converter. Isso te dá três caminhos para traduzir: entregar os arquivos a um TMS, fazer round-trip de arquivos de tradutor com export/import, ou traduzir por máquina com translate.
JSON plano, sem lock-in
A maioria dos TMS (Crowdin, Lokalise, Phrase e companhia) ingere JSON plano nativamente. Aponte a plataforma para locales/ e pronto: sem etapa de export, sem formato próprio. As traduções voltam como os mesmos arquivos, e cada mudança é revisada como um diff normal.
Export para humanos
Quando não há TMS (um tradutor freelance, uma agência, um colega com uma planilha), o verbaly export escreve um arquivo pronto para tradução por idioma, com o texto original ao lado de cada tradução. Se você guarda seu catálogo por grupos, ele exporta uma linha por mensagem, nomeada com seu caminho completo, então o tradutor vê texto e nunca um grupo.
npx verbaly export # verbaly-export/es.xlf, pt.xlf (XLIFF 2.0)
npx verbaly export --format csv # key,source,target,location (any spreadsheet)
npx verbaly export --format po # es.po, pt.po (gettext, any PO editor)
npx verbaly export --missing # only what's untranslatedXLIFF 2.0 é o formato de intercâmbio da indústria, então TMS e ferramentas CAT o abrem direto, e seus placeholders e tags viajam nele como fichas protegidas com nomes com sentido, então um tradutor não consegue quebrá-los por acidente (as palavras de plural e select seguem editáveis: essas sim se traduzem). Gettext PO funciona com Poedit e qualquer ferramenta PO. CSV é para todo o resto: editável em qualquer lugar. Todos os formatos dizem onde cada texto vive no seu código, então o tradutor vê o contexto em vez de adivinhar.
Antes de exportar, verbaly status mostra quanto falta por idioma: es: 45/48 translated (94%).
Import de volta, validado
verbaly import lê os arquivos traduzidos (XLIFF 2.0 ou 1.2, CSV ou gettext PO) e preenche seus catálogos. Cada entrada passa pela mesma validação estrutural da tradução por máquina: placeholders, variantes de plural e tags devem sobreviver intactos. O resto é rejeitado e reportado, nunca escrito.
npx verbaly import verbaly-export/es.xlf
# es: +42 imported
# es: 1 rejected (params/tags not preserved): home.greeting
npx verbaly import es.csv --dry-run # preview without writing
npx verbaly import es.xlf --overwrite # replace existing translationsAs traduções existentes são mantidas a menos que você passe --overwrite; keys desconhecidas são ignoradas e reportadas. Entradas que uma ferramenta PO marca como fuzzy contam como não traduzidas. O idioma de destino vem do próprio arquivo (ou do nome do arquivo), e --locale vence os dois.
A rede de segurança, em palavras simples
Editar locales/es.json à mão é uma forma perfeitamente válida de traduzir, e recebe a mesma proteção de um arquivo importado. verbaly check lê cada tradução ao lado do original e para o build quando a tradução não consegue dizer a mesma coisa. Você não precisa lembrar destas regras: se quebrar uma, o erro diz qual e onde.
- Mantenha cada
{placeholder}, escrito igual. É o espaço onde entra um nome, uma quantidade ou uma data. Traduza as palavras ao redor, nunca a de dentro. - Mantenha as tags em pares.
<em>…</em>e companhia marcam ênfase ou um link. Mova para onde a frase precisar, mas não deixe uma metade de fora. Palavras que só parecem uma tag são suas para traduzir: emPress <Enter> to continuenada fecha esse sinal, então nada está checando isso. - Mantenha o bloco de plural como bloco de plural, e conserve sempre o caso
other. Esse caso é o curinga: sem ele, qualquer quantidade que você não listou não mostra nada. - Adicione as formas que o seu idioma precisa. O inglês se resolve com duas, o polonês e o árabe precisam de mais. Verbaly avisa quais faltam, e esse aviso é um conselho, não uma falha.
npx verbaly status é a olhada rápida: quanto está traduzido por idioma, quanto espera revisão e quanto está quebrado.
Exportar para apps mobile
Os mesmos catálogos podem viajar para um app mobile irmão como recursos nativos: android-xml escreve pastas strings.xml que você solta em res/, e ios-strings escreve pastas .lproj para o Xcode.
npx verbaly export --format android-xml # verbaly-export/values-es/strings.xml, values-pt-rBR/…
npx verbaly export --format ios-strings # verbaly-export/es.lproj/Localizable.strings, …Seu idioma fonte vira o padrão da plataforma (values/strings.xml, en.lproj), e chaves sem tradução ficam de fora para o app fazer fallback a ele em vez de mostrar texto vazio. As keys são adaptadas a nomes de recurso válidos do Android, os valores mantêm sua sintaxe de parâmetros intacta, e o fluxo é de mão única: as traduções vão dos seus catálogos para o app.
Ainda sem humanos disponíveis?
A tradução por máquina preenche as lacunas com as mesmas garantias estruturais, e tudo o que um provider ou uma pessoa errar é pego pelo verbaly check no CI.
A saída da máquina chega marcada como rascunho: o translate registra o que escreveu em locales/.verbaly-drafts.json, commitado com seus catálogos e nunca editado à mão, então ninguém confunde com trabalho revisado.
npx verbaly translate # es: +12 translated (draft)
npx verbaly review # list what's waiting for a human
npx verbaly review --approve # accept after reading
npx verbaly check --drafts # CI gate: fail while drafts remainAntes da primeira execução, escreva o que não se traduz. Os nomes do seu produto, os das suas funções e qualquer forma que você já tenha decidido vão em translate.glossary, e como você trata o leitor vai em translate.instructions. Sai mais barato do que corrigir a mesma palavra à mão depois de cada execução.
Uma execução longa sobrevive a uma conexão ruim. As requisições que falham por algo passageiro são tentadas de novo, e se ainda assim uma não voltar, todo o resto fica salvo e o relatório nomeia as mensagens que não conseguiu preencher. Rodar translate de novo pede só essas, então uma execução interrompida nunca custa tudo duas vezes.
O verbaly review lista o que espera, verbaly review --approve aceita depois de ler, e um arquivo de tradutor trazido com import conta como revisão por si só. No CI, verbaly check --drafts continua falhando enquanto restarem rascunhos sem revisar.
Um agente de código pode rodar esse mesmo ciclo através do servidor MCP: o que ele traduzir continua chegando como rascunho atrás da mesma porta de revisão.