Guias

CLI

O binário verbaly vem com @verbaly/compiler (dependência do plugin do Vite), então npx verbaly funciona direto.

Comandos

ComandoO que faz
verbaly initGera config + catálogos de locales e sugere o plugin certo para seu bundler
verbaly doctorDiagnostica o setup (config, catálogos, plugin conectado, tipos desatualizados, keys órfãs) e diz o fix exato de cada achado
verbaly extractEscaneia 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 statusMostra a cobertura de tradução por idioma num relance (es: 45/48 translated), só informativo, nunca falha
verbaly checkVerifica se cada chave tem tradução em cada idioma. Sai com 1 em chaves faltando ou desconhecidas, feito para CI
verbaly translatePreenche os buracos "" que o check reporta via um provider de tradução, Claude por padrão
verbaly exportEscreve 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 importPreenche os catálogos a partir de arquivos XLIFF/CSV traduzidos, com cada entrada validada estruturalmente e as quebradas rejeitadas e reportadas
verbaly pseudoGera um catálogo pseudo-locale de QA (en-XA) a partir da fonte, expondo strings hardcoded e layouts cortados
verbaly renderPré-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/vite

Reexecutar é 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

FlagDefaultDescrição
--rootcwdRaiz do projeto
--dirlocalesDiretório de catálogos
--sourceenIdioma fonte
--localesdos arquivosIdiomas extras, separados por vírgula
--pruneoffRemove chaves sem referências (só no extract)
--watchoffRe-extrai quando os arquivos fonte mudam: extração viva para setups com webpack, Rspack e Rollup (só extract, 0.23.0)
--localeen-XAId do pseudo-locale (só pseudo)
--sitedistDiretó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 → extracttranslatecheck 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:

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

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:

verbaly.config.mjs
export default {
  sourceLocale: 'es',
  locales: ['es', 'en', 'pt'],
  dir: 'locales',
};

Exemplo de CI

.github/workflows/ci.yml
- run: pnpm install
- run: npx verbaly check   # fails the job on missing translations
- run: pnpm build
Copiado para a área de transferência