Framework

React

El paquete oficial de React 18/19 para Verbaly. Hooks sobre el mismo core reactivo, un <Trans> consciente del compilador 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/react

Setup y hooks

App.tsx
import { VerbalyProvider, useT, useLocale } from '@verbaly/react';
import { verbaly } from 'virtual:verbaly';

<VerbalyProvider instance={verbaly}>
  <App />
</VerbalyProvider>

function Inbox() {
  const t = useT();
  const [locale, setLocale] = useLocale();
  return <p>{t('inbox', { count: 3 })}</p>;
}

Rich text con <Trans>

Escribe el texto fuente en el lugar, y desde 0.6.0 el compilador lo extrae, exactamente como t`…`:

Agree.tsx
import { Trans } from '@verbaly/react';

// you write:
<Trans>Read the <a href='/terms'>terms</a> before continuing</Trans>

// the compiler extracts "Read the <a>terms</a> before continuing" and rewrites to:
<Trans id='x7Ka9q2f' components={{ a: <a href='/terms' /> }} />

Next.js

Los Server Components se renderizan ya traducidos al idioma del visitante, y los Client Components hidratan con el mismo locale y el mismo catálogo: sin flash de texto sin traducir ni mismatch de hidratación.

Next.js necesita la integración (@verbaly/next) junto a los bindings de React:

 pnpm add verbaly @verbaly/next @verbaly/react

Conéctalo

Envuelve tu config con withVerbaly. Cablea la extracción en vivo en dev, el compilador de mensajes en Turbopack y webpack, y bloquea next build si faltan traducciones:

next.config.ts
import { withVerbaly } from '@verbaly/next';

export default withVerbaly({ /* your Next config */ });

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

En el layout raíz, getVerbalyProps serializa el locale negociado y su catálogo, y VerbalyProvider siembra el cliente desde ellos:

app/layout.tsx
import { getRequestLocale, getVerbalyProps } from '@verbaly/next/server';
import { VerbalyProvider } from '@verbaly/next/client';

export default async function RootLayout({ children }) {
  const locale = await getRequestLocale();
  const props = await getVerbalyProps();
  return (
    <html lang={locale}>
      <body>
        <VerbalyProvider {...props}>{children}</VerbalyProvider>
      </body>
    </html>
  );
}

Server y Client Components

Los Server Components obtienen un t por request con await getT(), negociado una vez por request (cookie, luego Accept-Language, luego tu fallback):

app/page.tsx
import { getT } from '@verbaly/next/server';

export default async function Page() {
  const t = await getT();
  return <h1>{t`Welcome back`}</h1>;
}

Los Client Components usan los bindings de React, re-exportados desde @verbaly/next/client:

Counter.tsx
'use client';
import { useT } from '@verbaly/next/client';

export function Counter() {
  const t = useT();
  return <p>{t`You have new messages`}</p>;
}

Cambiar de idioma

useSwitchLocale cambia el cliente en vivo, escribe la cookie que el servidor lee, y re-renderiza los Server Components vía router.refresh():

LangPicker.tsx
'use client';
import { useSwitchLocale } from '@verbaly/next/client';

export function LangPicker() {
  const switchLocale = useSwitchLocale();
  return <button onClick={() => switchLocale('es')}>Español</button>;
}
Copiado en el portapapeles