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)
import { createVerbaly } from 'verbaly';
const v = createVerbaly({
locale: 'es',
fallback: ['en'],
messages: { es: { home: { title: 'Inicio' } } },
});| 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 a pedido. O do locale com que arrancas é pedido logo, e a UI atualiza quando chega |
| formatters | object | Formatters custom {v:name} |
| 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 contra as tuas mensagens. Dados maus de catálogo nunca quebram o render e também não passam ao lado: um param que falta, um bloco plural sem caso geral, um marcador sem o seu argumento, um valor que nem sequer é texto, cada um avisa uma vez na consola nomeando a mensagem ou o caminho 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) | Mescla mensagens em runtime: a primitiva do lazy-loading |
| 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
import { localeDirection, localeFromPath, localeName, localePath, negotiateLocale, persistLocale, resolveLocale, resolveRequestLocale, switchLocale } from 'verbaly';
// which language is this page? a fact of the url, undefined when it carries no prefix
localeFromPath({ supported: ['en', 'es', 'pt'] }) ?? 'en';
// which language does this visitor want? url prefix → storage → navigator → fallback
resolveLocale({ supported: ['en', 'es', 'pt'] });
persistLocale('es'); // localStorage + <html lang> + <html dir>
// server-side: match an Accept-Language header
negotiateLocale('es-PE,en;q=0.8', ['en', 'es']); // → 'es'
// per-request: cookie value → header → fallback
resolveRequestLocale({ supported: ['en', 'es'], cookie, header });
// client switch for SSR setups: catalog → locale → cookie + <html lang> + <html dir>
await switchLocale(instance, 'es');
// language switchers: names and direction from Intl, no tables
localeName('es'); // → 'español'
localeName('de', 'en'); // → 'German'
localeDirection('ar'); // → 'rtl'
// pre-rendered sites: the same page in another language, for a switcher that navigates
localePath('pt', { supported: ['en', 'es', 'pt'], sourceLocale: 'en' }); // /es/docs → /pt/docslocaleFromPath e resolveLocale respondem a duas perguntas diferentes, e escolher a errada é o erro 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 escreves localeFromPath(...) ?? sourceLocale e nada pode contradizer o url. resolveLocale(options) pergunta que idioma quer este visitante: prefixo do url, depois a escolha guardada, depois navigator.languages com narrowing BCP-47, depois fallback (path: false desliga o url). Usa-a para decidir para onde mandar alguém, nunca para decidir o que uma página já diz. persistLocale lembra uma mudança. As três são seguras em SSR, as duas primeiras aceitam um base para um site servido a partir de uma subpasta, e as de armazenamento aceitam um storageKey próprio (false desativa-o). Vê 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 (respeita os q-values, es-PE corresponde a es, sem diferenciar maiúsculas). Funciona com qualquer servidor; as integrações do SvelteKit, do Nuxt e do Next.js a usam por baixo.
resolveRequestLocale(options) toma a decisão inteira por request em uma só chamada: primeiro o valor de um cookie salvo, depois o header Accept-Language, depois seu fallback. LOCALE_STORAGE_KEY exporta o nome compartilhado (verbaly-locale) usado pelo storage do browser e pelo cookie SSR.
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.
Exports de baixo nível
Construindo ferramentas sobre o Verbaly? O pacote também exporta parse(message) (a AST da mensagem), parseTags(text) com RICH_TAGS (o tokenizador de texto rico e sua whitelist de tags, o que um renderer próprio precisa), flatten(tree) (árvore aninhada → keys com pontos), safeHref(href) e safeAttribute(name, value) (as proteções de URL e de atributos), e normalizeLink(link), o único normalizador de links que todos os adapters compartilham, mais o tipo RichLink. São as mesmas peças que o compilador usa.