Framework

Vue

El paquete oficial de Vue 3 para Verbaly. Composables con limpieza automática, un componente <Trans> para rich text, y claves + params totalmente tipados.

Qué puedes lograr:

Instalación

Instala el paquete con tu gestor de paquetes preferido.

 pnpm add @verbaly/vue

Setup y composables

main.ts
import { verbalyPlugin } from '@verbaly/vue';
import { verbaly } from 'virtual:verbaly';

app.use(verbalyPlugin(verbaly));
Inbox.vue
<script setup>
import { useT, useLocale } from '@verbaly/vue';

const t = useT();
const locale = useLocale();  // writable: locale.value = 'en'
</script>

<template>
  <p>{{ t('inbox', { count: 3 }) }}</p>
</template>

Escribe el texto en su lugar

Desde 0.20.0 el compilador también lee tus archivos .vue: escribe el texto fuente en el template, en un binding o en script setup, y se extrae, recibe su clave y sus tipos al guardar. Sin inventar claves, sin tocar catálogos.

Inbox.vue
<template>
  <p>{{ t`Hola ${user.name}` }}</p>
  <a :title="t`Abrir ajustes`">…</a>
</template>

<!-- extracted on save; the build rewrites both to t('key', …) -->

¿Prefieres claves legibles? t.id('inbox.title') antes del template extrae bajo tu id en vez de un hash del contenido.

Rich text con <Trans>

La misma idea; en Vue cada tag nombrado es una render function que envuelve a sus hijos:

Agree.vue
<script setup>
import { Trans } from '@verbaly/vue';
import { h } from 'vue';

const components = { terms: (c) => h('a', { href: '/terms' }, c) };
</script>

<template>
  <Trans id='agree' :components='components' />
</template>

Para links simples olvídate de la render function: el prop links (0.11.0) mapea nombres de tag a hrefs (un string o un objeto href/target/rel). components gana con el mismo nombre; los hrefs javascript: se bloquean.

Desde 0.23.0 los tags de la whitelist (<em>, <code>…) se renderizan como elementos reales sin necesidad de render function, la misma whitelist segura del intérprete de DOM; richTags la reemplaza, y el prop instance renderiza sin el plugin.

Nuxt

Las páginas renderizadas en el servidor llegan ya traducidas al idioma del visitante, y el cliente hidrata con el mismo locale y el mismo catálogo, sin flash de texto sin traducir ni mismatch de hidratación.

Nuxt necesita el módulo (@verbaly/nuxt) junto a los bindings de Vue:

 pnpm add verbaly @verbaly/nuxt @verbaly/vue

Conéctalo

Una línea en nuxt.config. El módulo cablea el plugin de Vite (extracción en vivo y virtual:verbaly), negocia el locale por request y mantiene el atributo lang sincronizado:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@verbaly/nuxt'],
});

// locales live in your verbaly.config (npx verbaly init), or inline:
export default defineNuxtConfig({
  modules: [['@verbaly/nuxt', { locales: ['en', 'es', 'pt'] }]],
});

De aquí en adelante es @verbaly/vue normal: useT() / useLocale() y <Trans> funcionan sin cambios en cada componente.

Cambiar de idioma

switchLocale (export del core desde 0.18.0) carga el catálogo primero, cambia en vivo y escribe la cookie que el servidor lee, así el próximo request SSR ya coincide:

LangPicker.vue
<script setup>
import { switchLocale } from 'verbaly';
import { useVerbaly } from '@verbaly/vue';

const verbaly = useVerbaly();
</script>

<template>
  <button @click="switchLocale(verbaly, 'es')">Español</button>
</template>
Copiado en el portapapeles