Guias
CLI
O binário verbaly vem com @verbaly/compiler (dependência do plugin do Vite), então npx verbaly funciona direto.
Comandos
| Comando | O que faz |
|---|---|
| verbaly init | Gera config + catálogos de locales e sugere o plugin certo para seu bundler |
| verbaly doctor | Diagnostica o setup (config, catálogos, plugin conectado, tipos desatualizados, keys órfãs) e diz o fix exato de cada achado |
| verbaly extract | Escaneia as fontes (.js/.ts/.jsx/.tsx, e .svelte/.vue desde 0.20.0), escreve as mensagens novas no catálogo fonte, adiciona placeholders "" ao resto e regenera verbaly.d.ts |
| verbaly status | Mostra a cobertura de tradução por idioma num relance (es: 45/48 translated), só informativo, nunca falha |
| verbaly check | Verifica se cada chave tem tradução em cada idioma. Sai com 1 em chaves faltando ou desconhecidas, feito para CI |
| verbaly translate | Preenche os buracos "" que o check reporta via um provider de tradução, Claude por padrão |
| verbaly export | Escreve arquivos XLIFF 2.0 ou CSV por idioma prontos para o tradutor, ou recursos nativos de Android e iOS para um app mobile irmão |
| verbaly import | Preenche os catálogos a partir de arquivos XLIFF/CSV traduzidos, com cada entrada validada estruturalmente e as quebradas rejeitadas e reportadas |
| verbaly pseudo | Gera um catálogo pseudo-locale de QA (en-XA) a partir da fonte, expondo strings hardcoded e layouts cortados |
| verbaly render | Pré-preenche o HTML data-verbaly por locale no seu site compilado, então páginas estáticas saem já traduzidas |
Scaffolding
verbaly init prepara um projeto em um comando: uma config tipada (.ts se você tem tsconfig, .mjs caso contrário), seu catálogo fonte mais um por --locales, e os próximos passos para o seu bundler: Vite → @verbaly/vite, o resto → @verbaly/unplugin.
npx verbaly init --locales es,pt
# created: verbaly.config.ts, locales/en.json, locales/es.json, locales/pt.json
# detected bundler: vite → pnpm add -D @verbaly/viteReexecutar é seguro: uma config ou catálogo existente é reportado como “kept” e fica intacto.
Checagem de saúde
verbaly doctor (0.13.0) é o irmão do init para projetos já rodando: inspeciona todo o setup e reporta cada achado com o comando exato que o corrige. Verde significa saudável; problemas saem com 1.
npx verbaly doctor
# ✓ config: verbaly.config.ts found
# ✓ catalogs: 3 locales (en, es, pt) in locales/
# ⚠ types: verbaly.d.ts is stale
# fix: run `npx verbaly extract`
# ⚠ orphans: 2 catalog keys are no longer referenced (old.title, hero.cta)
# fix: run `npx verbaly extract --prune` to drop them
# ✗ keys: 1 unknown key used in code (ghost.key)Um comando para responder “por que isto não traduz?” Ele checa sua config, seus catálogos e a ligação do plugin, se o verbaly.d.ts está atualizado, e qualquer key órfã ou faltando.
Chaves legíveis
As chaves hasheadas são o padrão sem config. Quando quiser ids legíveis, agrupados com namespaces de pontos, opte por mensagem com t.id:
t.id('inbox.title')`Hello ${name}`;
// extracted under "inbox.title" and rewritten to:
t('inbox.title', { name });Os catálogos continuam sendo JSON plano. Os pontos são só uma convenção de nomes. Ids dinâmicos (t.id(someVar)) não são tocados, e ids duplicados com textos diferentes disparam o warning de colisão de chaves.
Flags
| Flag | Default | Descrição |
|---|---|---|
| --root | cwd | Raiz do projeto |
| --dir | locales | Diretório de catálogos |
| --source | en | Idioma fonte |
| --locales | dos arquivos | Idiomas extras, separados por vírgula |
| --prune | off | Remove chaves sem referências (só no extract) |
| --watch | off | Re-extrai quando os arquivos fonte mudam: extração viva para setups com webpack, Rspack e Rollup (só extract, 0.23.0) |
| --locale | en-XA | Id do pseudo-locale (só pseudo) |
| --site | dist | Diretório do site compilado (só render) |
Desde 0.17.0 as flags são validadas por comando: uma flag que pertence a outro comando termina com um erro acionável em vez de ser ignorada em silêncio: translate --locale es avisa que você queria --locales.
Tradução de máquina
verbaly translate (0.9.0) fecha o ciclo: escrever → extract → translate → check verde. O provider padrão usa Claude (@anthropic-ai/sdk como peer opcional + ANTHROPIC_API_KEY); batches de 20 por request.
npx verbaly translate --dry-run # list what's missing, write nothing
npx verbaly translate --locales es,pt # fill only these locales
npx verbaly translate --model claude-opus-4-8 # override the default (claude-sonnet-5)Cada tradução é verificada: os placeholders e as tags precisam sobreviver intactos. Se um não sobrevive, a tradução é rejeitada e a entrada fica em "", então o check continua sinalizando até você corrigir.
Sem lock-in: conecte seu próprio provider no verbaly.config.ts:
export default {
translate: {
provider: async ({ sourceLocale, targetLocale, messages }) => ({ /* key → translation */ }),
},
};Tradutores e TMS
Humanos no ciclo? verbaly export (0.15.0) escreve arquivos XLIFF 2.0 ou CSV por idioma prontos para o tradutor e verbaly import os traz de volta, validados estruturalmente com o mesmo gate do translate. O fluxo completo, opções de TMS incluídas, vive em Trabalhar com tradutores.
Desde 0.22.0, export também escreve recursos nativos mobile: --format android-xml para o layout res/ do Android e --format ios-strings para o Xcode. Chaves sem tradução ficam de fora para o app fazer fallback ao seu idioma fonte (--missing vale só para os formatos de tradutor).
Renderização estática (SSG)
verbaly render (0.10.0) mata o flash de conteúdo não traduzido em sites estáticos: percorre seu HTML compilado e pré-preenche cada elemento data-verbaly por locale com o runtime real: plurais, formatação Intl, data-verbaly-args, tradução de atributos e rich text com whitelist.
npx vite build # or astro build, eleventy, …
npx verbaly render # dist/index.html filled in the source locale
# dist/es/index.html, dist/pt/… for the rest
npx verbaly render --site out --locales es # custom dir / locale filter- Cada cópia recebe seu
<html lang>; o locale fonte é preenchido in-place e o resto é espelhado paradist/<locale>/…. - Os atributos
data-verbalyficam no output, então a troca de idioma client-side continua funcionando sobre a página pré-renderizada. - As mensagens são escapadas como HTML (nunca injetadas), keys faltantes são reportadas e não são tocadas, e re-executar é idempotente.
- Links nomeados (
0.11.0): definarender.linksemverbaly.config.*(oudata-verbaly-linkspor elemento) e as mensagens rich pré-renderizam elementos<a href>reais, atributos escapados, comjavascript:bloqueado. - SEO multi-idioma (
0.14.0): definarender.baseUrle cada página recebe alternateshreflangrecíprocos;--sitemapgrava um sitemap i18n e--cleanremove páginas de locale obsoletas. - Espelhos self-canonical (
0.14.5):rel="canonical"eog:urlsão reescritos para a URL própria de cada idioma, porque um canonical cruzado faria os buscadores ignorarem o hreflang.
Pseudo-localização
verbaly pseudo (0.10.0) preenche um catálogo de QA (en-XA por padrão) a partir do locale fonte: letras acentuadas, marcadores ⟦…⟧ e ~33% de padding. Texto que sai limpo no build pseudo está hardcoded; layouts que cortam se revelam antes de uma tradução real.
npx verbaly pseudo # locales/en-XA.json
# "Hello {name}" → "⟦Ĥéĺĺó {name} ~⟧"Params, blocos de variantes e tags sobrevivem verbatim, garantido pela mesma validação estrutural do translate. Re-executar regenera o catálogo completo.
Arquivo de config
As flags vencem verbaly.config.{js,mjs,ts,mts,json} na raiz do projeto (os configs TS precisam do esbuild instalado). Mesmas opções do plugin do Vite, uma única fonte de verdade:
export default {
sourceLocale: 'es',
locales: ['es', 'en', 'pt'],
dir: 'locales',
};Exemplo de CI
- run: pnpm install
- run: npx verbaly check # fails the job on missing translations
- run: pnpm build