¿Cómo configuro Better i18n con Next.js?

El paquete `@better-i18n/next` se integra con el App Router de Next.js y agrega la obtención de mensajes via CDN con soporte ISR. Confíguralo en unos pocos pasos.

8 min de lecturaIntermedio

El paquete @better-i18n/next se integra con el App Router de Next.js y utiliza next-intl bajo el capó. Agrega la obtención de mensajes con CDN y soporte ISR.

Instalación

bun add @better-i18n/next next-intl

Paso 1: Crear la configuración i18n

Crea src/i18n.ts:

import { createI18n } from '@better-i18n/next';

export const i18n = createI18n({
  project: 'acme/dashboard',
  defaultLocale: 'en',
  localePrefix: 'as-needed', // 'always' | 'as-needed' | 'never'
  manifestRevalidateSeconds: 3600, // ISR: revalidar lista de locales cada hora
  messagesRevalidateSeconds: 30,   // ISR: revalidar mensajes cada 30s
});

Opciones de prefijo de locale

Opción URL de locale por defecto URL de otras locales
as-needed /about /tr/about
always /en/about /tr/about
never /about /about (locale desde cookie/encabezado)

Paso 2: Configurar el request config

Crea src/i18n/request.ts:

import { i18n } from '@/i18n';

export default i18n.requestConfig;

Esto le indica a next-intl cómo cargar mensajes para cada solicitud. Internamente, obtiene desde el CDN de Better i18n con caché ISR.

Paso 3: Añadir el middleware

Crea src/middleware.ts:

import { i18n } from '@/i18n';

export default i18n.betterMiddleware();

export const config = {
  matcher: ['/((?!api|_next|.*\\..*).*)'],
};

El middleware:

  • Detecta la locale preferida del usuario desde el encabezado Accept-Language
  • Redirige al prefijo de locale adecuado
  • Establece el encabezado x-better-locale para uso posterior

Paso 4: Añadir el provider

En tu layout raíz (src/app/[locale]/layout.tsx):

import { NextIntlClientProvider } from 'next-intl';
import { getMessages } from 'next-intl/server';

export default async function LocaleLayout({
  children,
  params: { locale },
}) {
  const messages = await getMessages();

  return (
    <html lang={locale}>
      <body>
        <NextIntlClientProvider messages={messages}>
          {children}
        </NextIntlClientProvider>
      </body>
    </html>
  );
}

Paso 5: Usar las traducciones

import { useTranslations } from 'next-intl';

export function WelcomeBanner() {
  const t = useTranslations('common');

  return (
    <div>
      <h1>{t('welcome_title')}</h1>
      <p>{t('welcome_description')}</p>
    </div>
  );
}

Variables de entorno

# .env.local
BETTER_I18N_PROJECT=acme/dashboard

La clave pública está integrada en el SDK — no se necesita clave API para el acceso CDN de solo lectura.

Cómo funciona el caché ISR

El SDK crea dos instancias internas de createI18nCore:

  • Manifest core — obtiene los locales disponibles, revalida cada manifestRevalidateSeconds (por defecto: 3600s)
  • Messages core — obtiene las traducciones, revalida cada messagesRevalidateSeconds (por defecto: 30s)

Esto significa que después de publicar nuevas traducciones, tu aplicación Next.js las recibe en ~30 segundos sin reconstrucción.

Próximos pasos

¿Te resultó útil este artículo?