Referência
API do runtime
O core do verbaly pesa ~3 KB gzip com zero dependências, e tudo se constrói sobre Intl nativo.
createVerbaly(options)
| Opção | Tipo | Descrição |
|---|---|---|
| locale | string | Idioma inicial; por padrão navigator.language no navegador |
| fallback | string | string[] | Cadeia de fallback após o narrowing BCP-47 (es-MX → es) |
| messages | object | Idioma → árvore; as chaves aninhadas achatam com pontos (home.title). Uma string vazia conta como não traduzida e segue o fallback, a mesma regra do check |
| loaders | object | Catálogos lazy: locale → () => import('./es.json'), carregados sob demanda. O do locale com que você inicia é pedido logo, e a UI atualiza quando chega |
| formatters | object | Formatters custom {v:name} |
| partial | string[] | Idiomas cujas mensagens vieram com a página: nada é buscado para eles, e uma mensagem que a página não mostrou carrega o resto uma vez em vez de cair no fallback em silêncio |
| onMissing | function | (key, locale): retorne uma string para substituir; silencia o warn-once padrão |
| onResolve | function | (info) em cada t(): key, locale, value e status (hit / fallback / miss). Alimenta os devtools |
Instância
| Membro | Descrição |
|---|---|
| t(key, params?) | Traduz. As chaves e os params são verificados por tipo contra as suas mensagens. Dados ruins nunca derrubam um render, e também não passam despercebidos: um param em falta, um bloco de plural sem caso geral, um espaço sem argumento, um valor que não é texto, um código de idioma que o navegador não consegue ler. Cada um avisa uma vez no console, nomeando a mensagem, o caminho ou o código de onde veio |
| t`...` | Tagged template: interpola texto fonte; o compilador o melhora |
| t.id(key)`...` | Chaves legíveis opt-in: formata o texto inline; o compilador o reescreve para uma chamada com chave |
| setLocale(locale) | Troca o idioma e notifica os assinantes, auto-carrega um catálogo lazy pendente |
| loadLocale(locale) | Carrega um catálogo lazy (narrowing BCP-47, deduplicado): faça await antes de setLocale para trocar sem flash |
| addMessages(locale, tree, options?) | Junta mensagens em tempo de execução: a primitiva do carregamento diferido. Passe { partial: true } quando as mensagens são as de uma só página, para que o idioma continue incompleto e a próxima mensagem em falta vá buscar o resto |
| subscribe(fn) | Listener de mudanças; retorna unsubscribe |
| has(key) | A chave existe na cadeia atual |
| inspect(key) | Locale de origem (from) + texto fonte de uma key (devtools/ferramentas) |
| locale | Idioma atual (readonly) |
| locales | Idiomas carregados + carregáveis (readonly): alimenta um switcher a partir de uma única fonte de verdade |
| version | Contador de mudanças que impulsiona os adapters de frameworks |
Helpers de idioma
localeFromPath e resolveLocale respondem a duas perguntas diferentes, e escolher a errada é o bug clássico. localeFromPath(options) pergunta em que idioma está esta página. Lê o prefixo /{locale}/ e devolve undefined quando o url não leva nenhum, por isso num site com uma árvore por idioma você escreve localeFromPath(...) ?? sourceLocale e nada pode contradizer o url. resolveLocale(options) pergunta que idioma quer este visitante: primeiro o prefixo do url, depois a escolha guardada, depois navigator.languages com estreitamento BCP-47, e depois o seu fallback (path: false desliga o url). Use-o para decidir para onde mandar alguém, nunca para decidir o que uma página já diz. persistLocale lembra uma troca. Todos são seguros em SSR. Os dois primeiros aceitam um base para um site servido a partir de uma subpasta, e os de armazenamento aceitam um storageKey próprio (false desliga o armazenamento). Veja HTML puro → Bootstrap de idioma para o padrão completo.
negotiateLocale(header, supported, fallback?) é a contraparte do lado do servidor: entregue a ela um header Accept-Language e seus locales e ela devolve a melhor correspondência. Ela respeita os q-values e não diferencia maiúsculas. Cada idioma encontra o locale suportado mais próximo: es-PE corresponde a es, zh-HK a zh-Hant, e pt ou pt-PT a pt-BR, mas nunca a um de outra escrita (zh-HK nunca recebe zh-Hans). Funciona com qualquer servidor; as integrações do SvelteKit, do Nuxt e do Next.js a usam por baixo.
resolveRequestLocale(options) toma toda a decisão por requisição numa só chamada. Dê a ele o path e o seu routing e decide o endereço: uma página com prefixo é esse idioma para todo mundo, e uma sem prefixo é o seu idioma de origem, por isso uma escolha guardada não a pode traduzir sem querer. Deixe o routing de fora e a ordem é primeiro o cookie guardado, depois o cabeçalho Accept-Language, depois o seu fallback. LOCALE_STORAGE_KEY exporta o nome compartilhado (verbaly-locale) que tanto o armazenamento do navegador como o cookie de SSR usam.
inlineMessages(root?) lê as mensagens que o verbaly render escreveu na página quando render.inlineCatalog está ligado, então uma página pré-traduzida não precisa de catálogo pela rede. Você raramente a chama: o módulo gerado já faz isso, e passa o resultado como partial para que uma mensagem que a página não mostrou ainda carregue quando precisar, em vez de cair no fallback em silêncio.
stripLocalePath(options) é o inverso de localePath: dá a rota por trás de um endereço com idioma, então um router consegue casar uma única árvore em vez de uma por idioma. alternateLinks(options) devolve o endereço desta página em todos os idiomas mais um x-default, pronto para as tags link rel="alternate" de um head renderizado no servidor. É o mesmo conjunto que verbaly render escreve em um site estático, e fica vazio quando seus endereços não levam idioma, porque um endereço só não pode dizer honestamente que é todos os idiomas ao mesmo tempo.
switchLocale(instance, locale, options?) é a troca de idioma do lado do cliente compartilhada pelas integrações SSR: carrega o catálogo primeiro, depois troca o locale, grava o cookie verbaly-locale e atualiza os atributos lang e dir. É seguro chamá-la no servidor (lá ela não faz nada); o @verbaly/sveltekit a re-exporta.
localeName(locale, displayIn?) e localeDirection(locale) alimentam um seletor de idioma sem tabelas fixas: nomes de idioma reais via Intl.DisplayNames (por padrão o nome no próprio idioma) e a direção de escrita de qualquer locale. Idiomas da direita para a esquerda não pedem trabalho extra: switchLocale, persistLocale, as integrações SSR e o verbaly render já mantêm o dir correto por conta própria.
Segurança em nível de tipos
v.t('home.title'); ✓
v.t('home.title', { x: 1 }); ✗ no params declared
v.t('nope'); ✗ unknown keyO TypeScript parseia suas mensagens: FlatKeys achata árvores aninhadas, ParamNames lê as ocorrências de {param}, e TArgs exige os params exatamente quando a mensagem os declara.
Com o compilador, os tipos gerados preenchem Register, então Translate é o t do seu projeto e Locale a união dos seus idiomas: cada t que um adaptador entrega (useT(), getT()) e cada instância do módulo gerado conferem chaves e params contra o seu catálogo. Uma instância que você cria a partir de um dicionário mantém os tipos desse dicionário. Os três são só tipos, então não custam nada em tempo de execução.
Exports de baixo nível
Você está construindo ferramentas por cima do Verbaly? O pacote exporta as mesmas peças que o compilador usa. parse(message) te dá a AST da mensagem, e parseTags(text) com RICH_TAGS é o tokenizador de texto rico e a sua whitelist de etiquetas, que é o que um renderizador próprio precisa. flatten(tree) transforma uma árvore aninhada em chaves com pontos. safeHref(href) e safeAttribute(name, value) são as guardas de url e de atributos, e normalizeLink(link) é o único normalizador de links que todos os adaptadores compartilham, juntamente com o tipo RichLink.