Referencia

API del runtime

El core de verbaly pesa ~3 KB gzip con cero dependencias, y todo se construye sobre Intl nativo.

createVerbaly(options)

import { createVerbaly } from 'verbaly';

const v = createVerbaly({
  locale: 'es',
  fallback: ['en'],
  messages: { es: { home: { title: 'Inicio' } } },
});
OpciónTipoDescripción
localestringIdioma inicial; por defecto navigator.language en el navegador
fallbackstring | string[]Cadena de fallback tras el narrowing BCP-47 (es-MXes)
messagesobjectIdioma → árbol; las claves anidadas se aplanan con puntos (home.title). Un string vacío cuenta como sin traducir y sigue el fallback, la misma regla que check
loadersobjectCatálogos lazy: idioma → () => import('./es.json'), cargados bajo demanda
formattersobjectFormatters custom {v:name}
onMissingfunction(key, locale): devuelve un string para sustituir; silencia el warn-once por defecto
onResolvefunction(info) en cada t(): key, locale, value y status (hit / fallback / miss). Alimenta los devtools

Instancia

MiembroDescripción
t(key, params?)Traduce; claves y params se verifican en tipos desde tus mensajes
t`...`Tagged template: interpola texto fuente; el compilador lo mejora
t.id(key)`...`Claves legibles opt-in: formatea el texto inline; el compilador lo reescribe a una llamada con clave
setLocale(locale)Cambia el idioma y notifica a los suscriptores, auto-carga un catálogo lazy pendiente
loadLocale(locale)Carga un catálogo lazy (narrowing BCP-47, deduplicado): haz await antes de setLocale para cambiar sin flash
addMessages(locale, tree)Fusiona mensajes en runtime: la primitiva del lazy-loading
subscribe(fn)Listener de cambios; devuelve unsubscribe
has(key)La clave existe en la cadena actual
inspect(key)Locale de origen (from) + texto fuente de una key (devtools/herramientas). El campo se renombró de locale en 0.17.0 (breaking) para alinearse con ResolveInfo.from
localeIdioma actual (readonly)
localesIdiomas cargados + cargables (readonly): alimenta un switcher desde una sola fuente de verdad
versionContador de cambios que impulsa los adapters de frameworks

Helpers de idioma

import { negotiateLocale, persistLocale, resolveLocale, resolveRequestLocale, switchLocale } from 'verbaly';

resolveLocale({ supported: ['en', 'es', 'pt'] });  // storage → navigator → fallback
persistLocale('es');                             // localStorage + <html lang>

// server-side (0.16.0): match an Accept-Language header
negotiateLocale('es-PE,en;q=0.8', ['en', 'es']);   // → 'es'

// per-request (0.17.0): cookie value → header → fallback
resolveRequestLocale({ supported: ['en', 'es'], cookie, header });

// client switch for SSR setups (0.18.0): catalog → locale → cookie + <html lang>
await switchLocale(instance, 'es');

resolveLocale elige el idioma inicial (elección guardada, luego navigator.languages con narrowing BCP-47, luego fallback); persistLocale recuerda un cambio. Ambos son SSR-safe y aceptan un storageKey custom (false desactiva el storage). Ver HTML plano → Bootstrap de idioma para el patrón completo.

negotiateLocale(header, supported, fallback?) (0.16.0) es la contraparte del lado servidor: dale un header Accept-Language y tus locales y devuelve la mejor coincidencia (respeta los q-values, es-PE coincide con es, sin distinguir mayúsculas). Funciona con cualquier servidor; las integraciones de SvelteKit, Nuxt y Next.js la usan por debajo.

resolveRequestLocale(options) (0.17.0) toma toda la decisión por request en una sola llamada: primero el valor de una cookie guardada, luego el header Accept-Language, luego tu fallback. LOCALE_STORAGE_KEY exporta el nombre compartido (verbaly-locale) que usan el storage del browser y la cookie SSR.

switchLocale(instance, locale, options?) (0.18.0) es el cambio de idioma del lado cliente que comparten las integraciones SSR: carga el catálogo primero, luego cambia el locale, escribe la cookie verbaly-locale y actualiza el atributo lang. Es seguro llamarlo en el servidor (ahí no hace nada); @verbaly/sveltekit lo re-exporta.

Seguridad a nivel de tipos

editor
v.t('home.title');            
v.t('home.title', { x: 1 });  ✗ no params declared
v.t('nope');                  ✗ unknown key

TypeScript parsea tus mensajes: FlatKeys aplana árboles anidados, ParamNames lee las apariciones de {param}, y TArgs exige los params exactamente cuando el mensaje los declara.

Exports de bajo nivel

¿Construyes herramientas sobre Verbaly? El paquete también exporta parse(message) (el AST del mensaje), flatten(tree) (árbol anidado → dot-keys), safeHref(href) (el guardián de esquemas inseguros detrás de los named links) y, desde 0.17.0, normalizeLink(link), el normalizador de links único que comparten todos los adapters, más el tipo RichLink. Son las mismas piezas que usa el compilador.

Copiado en el portapapeles