
Guía completa de internacionalización en Next.js
Configure next-intl con App Router, prepare el enrutamiento regional y automatice las traducciones con IA.
Instalar next-intl
next-intl es un único paquete que gestiona el enrutamiento regional, la carga de mensajes y los hooks de traducción para App Router de Next.js.
npm install next-intlCrear la configuración de solicitudes de i18n
Cree dos archivos: src/i18n/request.ts para cargar los mensajes y src/i18n/routing.ts para definir las configuraciones regionales. Determinan cómo resuelve next-intl los mensajes y las rutas.
// src/i18n/routing.ts
import { defineRouting } from 'next-intl/routing';
import { createNavigation } from 'next-intl/navigation';
export const routing = defineRouting({
locales: ['en', 'de', 'ja', 'es'],
defaultLocale: 'en',
localePrefix: 'as-needed', // /about for en, /de/about for de
});
export const { Link, redirect, usePathname, useRouter } =
createNavigation(routing);Configurar el middleware
Añada middleware.ts para gestionar la detección regional, la reescritura de URL y las redirecciones. El middleware intercepta cada solicitud y garantiza que se aplique la configuración correcta.
// middleware.ts <- Must be in project ROOT, not src/
import createMiddleware from 'next-intl/middleware';
import { routing } from './src/i18n/routing';
export default createMiddleware(routing);
export const config = {
matcher: ['/((?!api|_next|.*\\..*).*)'],
};Configurar la estructura de carpetas [locale]
Mueva las rutas de la aplicación dentro de app/[locale]/. Añada generateStaticParams para generar páginas de cada configuración regional durante la compilación. Así se crea la estructura de URL /en/about, /de/about, etc.
// app/[locale]/layout.tsx
import { routing } from '@/i18n/routing';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}Actualizar el diseño raíz
Cargue los mensajes con getMessages() y páselos a NextIntlClientProvider en el diseño regional raíz. Defina el atributo lang de html a partir del parámetro regional.
// app/[locale]/layout.tsx
import { NextIntlClientProvider } from 'next-intl';
import { getMessages, setRequestLocale } from 'next-intl/server';
import { routing } from '@/i18n/routing';
import { notFound } from 'next/navigation';
export function generateStaticParams() {
return routing.locales.map((locale) => ({ locale }));
}
export default async function LocaleLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
const { locale } = await params;
if (!routing.locales.includes(locale as any)) notFound();
setRequestLocale(locale);
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider locale={locale} messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
}Utilizar traducciones en los componentes
Los componentes de servidor utilizan getTranslations —asíncrono, con await—. Los componentes de cliente utilizan useTranslations —un hook—. Elija según dónde se renderice el componente; los de servidor mantienen las traducciones completamente fuera del paquete JavaScript del cliente.
// Server Component (default)
import { getTranslations, setRequestLocale } from 'next-intl/server';
export default async function AboutPage({
params,
}: { params: { locale: string } }) {
const { locale } = await params;
setRequestLocale(locale);
const t = await getTranslations('AboutPage');
return <h1>{t('title')}</h1>;
}
// Client Component ('use client')
'use client';
import { useTranslations } from 'next-intl';
export default function SearchBar() {
const t = useTranslations('SearchBar');
return <input placeholder={t('placeholder')} />;
}Añadir SEO: metadatos y hreflang
Utilice generateMetadata para producir títulos y descripciones de página específicos de cada configuración regional. Añada alternates.languages para las etiquetas hreflang y permita que los motores de búsqueda descubran todas las versiones lingüísticas de cada página.
// app/[locale]/layout.tsx or any page.tsx
import { getTranslations } from 'next-intl/server';
import { routing } from '@/i18n/routing';
export async function generateMetadata({
params,
}: { params: { locale: string } }) {
const { locale } = await params;
const t = await getTranslations({ locale, namespace: 'Metadata' });
return {
title: t('title'),
description: t('description'),
alternates: {
languages: Object.fromEntries(
routing.locales.map((l) => [l, `/${l}`])
),
},
};
}Gestionar páginas de error y no encontrado
error.tsx y not-found.tsx necesitan un tratamiento especial porque pueden renderizarse fuera del diseño regional normal. not-found.tsx en la raíz requiere su propia configuración del proveedor de i18n para mostrar mensajes de error localizados.
// app/[locale]/error.tsx
'use client';
import { useTranslations } from 'next-intl';
export default function Error() {
const t = useTranslations('Error');
return (
<div>
<h1>{t('title')}</h1>
<p>{t('description')}</p>
</div>
);
}
// app/not-found.tsx (root level -- needs own provider)
import { routing } from '@/i18n/routing';
export default async function GlobalNotFound() {
return (
<html lang={routing.defaultLocale}>
<body>
<h1>404 - Page Not Found</h1>
</body>
</html>
);
}Automatizar traducciones
Cuando termine de configurar i18n, traduzca los archivos de mensajes con IA directamente desde su IDE o utilice la CLI de i18n Agent en el proceso de CI/CD para automatizar la traducción en cada implementación.
# In your IDE, ask your AI assistant:
> Translate messages/en.json to German, Japanese, and Spanish
✓ messages/de.json created (1.1s)
✓ messages/ja.json created (1.4s)
✓ messages/es.json created (1.0s)Automatizar la calidad de la traducción
Herramientas de código abierto para i18n en Next.js
Estos paquetes de código abierto resuelven problemas habituales de los flujos de internacionalización en Next.js.
next-intl-localechain
next-intl estándar pasa directamente a la configuración regional predeterminada cuando falta una traducción. Un usuario de portugués de Brasil ve inglés en lugar de traducciones pt-PT perfectamente válidas. next-intl-localechain añade cadenas de respaldo inteligentes: combina en profundidad las traducciones de configuraciones relacionadas para que los usuarios regionales vean siempre la traducción disponible más próxima.
import { getRequestConfig } from 'next-intl/server';
import { withLocaleChain } from 'next-intl-localechain';
export default getRequestConfig(withLocaleChain({
loadMessages: (locale) =>
import(`../../messages/${locale}.json`).then(m => m.default),
defaultLocale: 'en'
}));@i18n-agent/cli
Una herramienta de línea de comandos para traducir sus archivos de mensajes de Next.js sin salir del terminal. Traduzca archivos directamente, consulte el estado de los trabajos y descargue los resultados. Funciona en procesos de CI/CD con autenticación mediante clave de API para automatizar por completo los flujos de localización.
# Install the CLI
npm install -g @i18n-agent/cli
# Authenticate
i18nagent login
# Translate your message files
i18nagent translate ./messages/en.json --lang de,ja,es
# Or use in CI/CD with an API key
export I18N_AGENT_API_KEY=your-key-here
i18nagent translate ./messages/en.json --lang de,ja,esErrores habituales
«Unable to find next-intl locale»
El middleware no coincidió con la solicitud. Compruebe: ¿está middleware.ts en la raíz del proyecto? ¿Excluye correctamente los archivos estáticos el patrón matcher? ¿Está incluida la configuración regional en su enrutamiento?
Renderizado dinámico inesperado
Falta setRequestLocale(locale) en una página o diseño. Sin él, next-intl utiliza cabeceras o cookies para detectar la configuración regional, lo que fuerza el renderizado dinámico e impide la generación estática.
Las rutas paralelas se rompen con i18n
Las rutas paralelas (@modal) y las rutas de intercepción ((.)photo) presentan incompatibilidades conocidas con el segmento dinámico [locale]. Utilice el enrutamiento mediante middleware como solución para estos patrones avanzados.
El cambio de idioma pierde la ruta actual
Al cambiar de configuración regional, conserve el pathname actual mediante usePathname() y sustituya únicamente el segmento regional. Tenga cuidado con los parámetros de rutas dinámicas: deben volver a resolverse para la nueva configuración.
Estructura de archivos recomendada
my-nextjs-app/
├── middleware.ts # Locale routing (project root!)
├── next.config.mjs
├── messages/
│ ├── en.json # Source messages
│ ├── de.json
│ └── ja.json
├── src/
│ ├── i18n/
│ │ ├── request.ts # Message loading config
│ │ └── routing.ts # Locale definitions
│ └── app/
│ └── [locale]/
│ ├── layout.tsx # Root locale layout
│ ├── page.tsx # Home page
│ ├── error.tsx # Localized error page
│ ├── not-found.tsx # Localized 404
│ └── about/
│ └── page.tsx
└── package.jsonTambién puede traducir:
Pruebe i18n Agent ahora
Arrastre y suelte aquí su archivo de traducción
JSON, YAML, PO, XML, CSV, Markdown, Properties
o haga clic para seleccionar
Idiomas de destino
Respaldo de configuraciones regionales con next-intl-localechain
Cuando falta una clave de traducción en una configuración regional como pt-BR, next-intl pasa directamente a la predeterminada en vez de comprobar primero la principal pt.
npm install next-intl-localechainimport { withLocaleChain } from 'next-intl-localechain';
export default withLocaleChain({
fallbacks: {
'pt-BR': ['pt', 'en'],
'zh-Hant-HK': ['zh-Hant', 'zh', 'en'],
},
defaultLocale: 'en',
loadMessages: (locale) => import(`./messages/${locale}.json`),
});Consulte nuestra guía de respaldo de configuraciones regionales para ver todos los frameworks admitidos y las 75 cadenas integradas. Learn more →