Framework

Vue

O pacote oficial de Vue 3 para Verbaly. Composables com limpeza automática, um componente <Trans> para rich text, e chaves + params totalmente tipados.

O que você pode fazer:

Instalação

Instale o pacote com o seu gerenciador de pacotes preferido.

 pnpm add @verbaly/vue

Setup e 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>

Escreva o texto no lugar

Desde 0.20.0 o compilador também lê seus arquivos .vue: escreva o texto fonte no template, em um binding ou no script setup, e ele é extraído, ganha sua chave e seus tipos ao salvar. Sem inventar chaves, sem tocar em 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', …) -->

Prefere chaves legíveis? t.id('inbox.title') antes do template extrai sob o seu id em vez de um hash do conteúdo.

Rich text com <Trans>

A mesma ideia; no Vue cada tag nomeado é uma render function que envolve seus filhos:

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 dispense a render function: a prop links (0.11.0) mapeia nomes de tag para hrefs (uma string ou um objeto href/target/rel). components ganha no mesmo nome; hrefs javascript: são bloqueados.

Desde 0.23.0 as tags da whitelist (<em>, <code>…) renderizam como elementos reais sem precisar de render function, a mesma whitelist segura do interpretador de DOM; richTags a substitui, e a prop instance renderiza sem o plugin.

Nuxt

As páginas renderizadas no servidor chegam já traduzidas no idioma do visitante, e o cliente hidrata com o mesmo locale e o mesmo catálogo, sem flash de texto sem tradução nem mismatch de hidratação.

O Nuxt precisa do módulo (@verbaly/nuxt) junto aos bindings do Vue:

 pnpm add verbaly @verbaly/nuxt @verbaly/vue

Conecte tudo

Uma linha no nuxt.config. O módulo conecta o plugin do Vite (extração ao vivo e virtual:verbaly), negocia o locale por request e mantém o 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'] }]],
});

Daqui em diante é @verbaly/vue normal: useT() / useLocale() e o <Trans> funcionam sem mudanças em cada componente.

Trocar de idioma

switchLocale (export do core desde o 0.18.0) carrega o catálogo primeiro, troca ao vivo e grava o cookie que o servidor lê, então o próximo request SSR já corresponde:

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 para a área de transferência