Guía de localización de Next.js
Localización de Next.js para App Router y Pages Router
Crea rutas que tengan en cuenta la configuración regional, carga mensajes de forma eficiente en Server y Client Components, compara next-intl con next-i18next y publica páginas localizadas rastreables con los metadatos correctos.
La base de una aplicación Next.js localizada
Next.js es una base sólida para sitios multilingües porque puede renderizar HTML útil antes de que el navegador ejecute el JavaScript de la aplicación. La generación estática funciona bien para páginas de producto y documentación; el renderizado dinámico puede servir contenido específico de una cuenta o que cambia con frecuencia. Ninguno de los dos modos de renderizado crea por sí solo una estrategia de localización. Sigues necesitando rutas sensibles a la configuración regional, catálogos, reglas de formato y un flujo de traducción.
La primera decisión arquitectónica es el router. App Router utiliza layouts, Server Components y segmentos de ruta. Su patrón oficial de localización sitúa el idioma en un segmento dinámico de nivel superior como app/[lang]. Pages Router cuenta con una configuración i18n independiente que puede añadir enrutamiento por subrutas o dominios y exponer datos de configuración regional a las páginas. Estos sistemas no deben describirse como intercambiables.
Convierte la configuración regional en un concepto validado de la aplicación en lugar de pasar texto arbitrario de la URL a las importaciones de catálogos. Mantén una única lista de configuraciones regionales compatibles con el código, el nombre visible, la dirección del texto y el respaldo. Usa esa lista para generar rutas, crear un selector de idioma, elegir catálogos y emitir metadatos. Una solicitud de una configuración regional no compatible debe resolverse de forma predecible con una respuesta de página no encontrada o un respaldo intencionado.
- Una URL estable para cada configuración regional y página de contenido
- Un límite de carga de catálogos que funcione en el servidor
- Una política deliberada de detección, respaldo y cambio
- Metadatos localizados y señales de páginas alternativas para los rastreadores
Elige una estrategia de enrutamiento por configuración regional
El enrutamiento por subrutas ofrece una URL visible para cada idioma, como /en/pricing y /fr/pricing. Funciona en un único dominio, es fácil de probar y convierte el cambio de idioma en una transformación de la ruta. El enrutamiento por dominios, como example.fr, puede admitir una marca o unos requisitos legales específicos de cada mercado, pero añade trabajo de DNS, despliegue, analítica y canonicalización. Elige dominios por motivos de producto, no porque la localización los requiera.
En App Router, coloca todas las páginas localizadas bajo app/[locale]. Un Proxy puede inspeccionar el nombre de la ruta, una cookie o la cabecera Accept-Language en el momento de la solicitud y redirigir una URL de entrada neutra a una configuración regional. Next.js 16 cambió el nombre de middleware.ts a proxy.ts, aunque las aplicaciones antiguas siguen usando el término middleware. Considera la negociación una comodidad: cada URL localizada debe seguir siendo accesible directamente y el selector debe usar enlaces ordinarios rastreables.
Una exportación puramente estática no puede ejecutar Proxy, leer cookies de la solicitud ni realizar redirecciones en el momento de la solicitud. Para output: 'export', enumera los segmentos de configuración regional con generateStaticParams y proporciona una experiencia de entrada estática, como una página de inicio con una configuración regional predeterminada o un selector de idioma visible. No prometas detección automática del idioma del navegador en un entorno sin un tiempo de ejecución para solicitudes.
La opción i18n de next.config.js de Pages Router admite subrutas y dominios de configuración regional en aplicaciones Next.js desplegadas. No es compatible con output: 'export'. Si un proyecto con Pages Router debe generar únicamente archivos estáticos, modela la configuración regional como un segmento dinámico explícito y genera esas rutas en lugar de activar el campo i18n integrado. La generación estática y la exportación estática están relacionadas, pero no son el mismo modo de despliegue.
app/
[locale]/
layout.tsx
page.tsx
pricing/
page.tsx
messages/
en.json
fr.json
de.json next-intl frente a next-i18next frente a diccionarios personalizados
Una biblioteca debe reducir la infraestructura repetida sin ocultar cómo funcionan las URL de configuración regional y el renderizado. Compara la compatibilidad con tu router, la carga de mensajes en servidor y cliente, la sintaxis de ICU o i18next, la generación estática, las utilidades de enrutamiento y las herramientas de extracción. No elijas basándote únicamente en un ejemplo inicial: la localización afecta a la navegación, los metadatos, los errores, los formularios y el contenido en segundo plano de toda la aplicación.
Actualmente, tanto next-intl como next-i18next son compatibles con App Router y Pages Router, pero mantienen modelos mentales distintos. next-intl se centra en los mensajes ICU y el enrutamiento adaptado a Next.js. next-i18next incorpora el ecosistema de i18next, incluidos espacios de nombres, detectores, cargadores y API conocidas al estilo de react-i18next. Un enfoque de diccionarios personalizados tiene una superficie de abstracción menor, pero transfiere más responsabilidad al código de tu aplicación.
| Enfoque | Enrutamiento | Modelo de mensajes | Server Components | Generación estática | Opción ideal |
|---|---|---|---|---|---|
| next-intl | Se prefiere App Router; compatible con Pages | Mensajes y formateadores ICU | API para Server y Client Components | Compatible con parámetros estáticos de configuración regional | Aplicaciones centradas en Next.js que utilizan ICU |
| next-i18next | App Router y Pages Router | Claves y espacios de nombres de i18next; ICU opcional | API getT en el servidor y useT en el cliente | Compatible con generación explícita de configuraciones regionales | Equipos que ya utilizan i18next |
| Next.js + diccionarios personalizados | Rutas [locale] explícitas | La estructura JSON o de módulo que elijas | Carga natural en Server Components | Sí, cuando las rutas son enumerables | Sitios pequeños con mensajes sencillos |
Para una aplicación nueva con App Router, mensajes complejos y navegación localizada, next-intl es una opción predeterminada bien enfocada. Para una organización que ya utiliza i18next o una aplicación compartida con otras interfaces de React, next-i18next puede conservar las convenciones de catálogos y complementos. Revisa la configuración específica de cada versión antes de migrar: ambas bibliotecas han evolucionado considerablemente a medida que Next.js ha cambiado sus API de servidor.
La opción de usar solo el framework es razonable cuando el catálogo es pequeño, los mensajes son sencillos y el equipo acepta crear sus propias herramientas de validación y extracción. Cargar un diccionario en un Server Component evita que su contenido llegue al cliente, pero las primitivas de enrutamiento no proporcionan sintaxis de plurales, contexto para traductores, validación de catálogos ni flujos de revisión. Añade estas capacidades solo cuando el producto las necesite y mantén el acceso al catálogo detrás de una interfaz pequeña.
Una configuración de App Router lista para producción
La siguiente secuencia utiliza una aplicación con App Router porque expone las decisiones a las que se enfrentan la mayoría de los proyectos nuevos. Las importaciones exactas varían según la biblioteca, pero los límites se mantienen estables: valida la configuración regional en la ruta, carga los mensajes de servidor para esa solicitud, proporciona únicamente lo que necesitan los Client Components y genera las configuraciones regionales conocidas durante la compilación cuando la página pueda ser estática.
-
Paso 1
Añadir el segmento de ruta de configuración regional
Crea app/[locale] y coloca debajo los layouts y las páginas localizados. Valida params con una única lista de configuraciones regionales compatibles y devuelve una respuesta de página no encontrada para los valores desconocidos.
-
Paso 2
Definir la negociación y el respaldo
Decide qué ocurre en una URL sin configuración regional. Un entorno de ejecución para solicitudes puede negociar y redirigir; una exportación estática necesita una página predeterminada determinista o un selector de idioma. Conserva siempre el acceso directo a las URL de configuración regional.
-
Paso 3
Crear catálogos de mensajes acotados
Organiza los mensajes por área de producto o ruta en lugar de colocar toda la aplicación en un único archivo. Mantén la misma estructura de espacios de nombres en todas las configuraciones regionales, valida las claves que faltan en CI y evita importar todos los idiomas en un Client Component.
-
Paso 4
Cargar mensajes en el servidor
Resuelve un catálogo validado para cada solicitud o ruta generada. Cuando la biblioteca almacene el estado de la configuración regional activa, mantén las instancias del servidor acotadas a la solicitud para impedir que las solicitudes simultáneas filtren sus elecciones de idioma.
-
Paso 5
Separar la traducción en servidor y cliente
Traduce en Server Components de forma predeterminada. Añade un proveedor o hook de cliente únicamente en torno al límite interactivo más pequeño que lo necesite y pasa etiquetas traducidas como propiedades cuando resulte más sencillo.
-
Paso 6
Generar variantes de configuración regional
Devuelve cada configuración regional compatible desde generateStaticParams para las páginas estáticas. El contenido dinámico también puede requerir combinaciones de slug y configuración regional. Vuelve a compilar cada vez que cambien los catálogos o la lista de configuraciones regionales.
import {NextIntlClientProvider} from 'next-intl';
import {getMessages} from 'next-intl/server';
export default async function LocaleLayout({children, params}: Props) {
const {locale} = await params;
const messages = await getMessages();
return (
<html lang={locale}>
<body>
<NextIntlClientProvider messages={messages}>
{children}
</NextIntlClientProvider>
</body>
</html>
);
} const locales = ['en', 'fr', 'de'] as const;
export function generateStaticParams() {
return locales.map((locale) => ({locale}));
} Haz que el layout raíz de la configuración regional se encargue de las cuestiones comunes a todo el idioma: validar params, cargar el catálogo, definir html lang y dir, y establecer cualquier proveedor de cliente. Las páginas deben solicitar mensajes por espacio de nombres sin saber dónde residen los catálogos. Esta separación permite sustituir las importaciones JSON locales por una descarga durante la compilación o un flujo respaldado por una CDN sin reescribir cada componente.
Para Pages Router, traslada las mismas responsabilidades al enrutamiento por configuración regional de next.config.js, a la carga de mensajes mediante getStaticProps o getServerSideProps y a getStaticPaths para las páginas dinámicas localizadas. Las API del router son distintas, pero las capas de catálogo y de componentes pueden seguir siendo coherentes. Durante una migración, admite ambos routers de forma deliberada y verifica que la navegación nunca elimine el prefijo de configuración regional.
Formato, plurales y diseños de derecha a izquierda
El formato está estrechamente relacionado con la traducción, pero no es la misma tarea. Los mensajes explican qué significa un valor; los formateadores sensibles a la configuración regional deciden cómo se muestra una fecha, un número, una moneda, un tiempo relativo o una lista. Las integraciones de next-intl e i18next ofrecen utilidades de formato, mientras que una capa de diccionarios personalizada puede llamar directamente a las API Intl de la plataforma. Conserva las fechas y los números sin procesar como datos hasta el límite de renderizado para que un mismo valor de origen pueda presentarse correctamente en cada configuración regional.
Las reglas de plural también pertenecen al idioma de destino, no a una condición inglesa de singular frente a plural. Los mensajes ICU pueden seleccionar categorías como one, few, many y other. i18next asigna los valores de count mediante Intl.PluralRules. En ambos casos, pasa el recuento numérico al mensaje y deja que la biblioteca elija la forma gramatical. No concatentes un sustantivo traducido con un número formateado.
Establece el atributo lang de html a partir de la configuración regional validada de la ruta y dir como rtl para las escrituras de derecha a izquierda. El idioma no determina automáticamente la dirección en HTML, así que define la dirección como una propiedad explícita de la configuración regional. Refleja el espaciado direccional y los iconos cuando su significado dependa de la dirección, y usa propiedades CSS lógicas para que los diseños se adapten sin una segunda hoja de estilos.
export async function generateMetadata({params}: Props) {
const {locale} = await params;
const t = await getTranslations({locale, namespace: 'Metadata'});
return {
title: t('title'),
description: t('description'),
alternates: {
canonical: `https://example.com/${locale}`,
languages: {en: '/en', fr: '/fr', de: '/de'}
}
};
} SEO multilingüe para Next.js
El HTML renderizado es solo el comienzo del SEO multilingüe. Los motores de búsqueda necesitan una URL distinta y estable para cada versión lingüística, además de enlaces claros entre las alternativas. En App Router, generateMetadata puede generar títulos y descripciones localizados junto con alternates.canonical y alternates.languages. Un sitemap también puede enumerar idiomas alternativos. Aplica una política de URL coherente para que los metadatos, la navegación y las entradas del sitemap nunca se contradigan.
Cada página localizada debe hacer referencia a sí misma y a todas las configuraciones regionales equivalentes mediante anotaciones hreflang recíprocas. Usa URL absolutas en producción y añade x-default cuando resulte útil un selector neutro o una experiencia predeterminada. Una URL canónica suele apuntar a la versión del idioma actual, no automáticamente al inglés. Cuando una página no esté disponible en una configuración regional, omite esa alternativa no compatible en lugar de enviar a los rastreadores a contenido no relacionado.
No dependas únicamente de Accept-Language. Googlebot suele rastrear sin una preferencia de idioma útil y el contenido adaptado a la configuración regional bajo una misma URL puede ocultar variantes. Mantén las páginas de cada configuración regional accesibles mediante enlaces normales. Define html lang para los navegadores y las tecnologías de asistencia, pero recuerda que Google determina el idioma principalmente a partir del contenido visible, por lo que la traducción debe ser sustancial y coherente.
- Devuelve HTML localizado completo en una URL estable y rastreable.
- Localiza el título, la descripción, los encabezados y el cuerpo visible, no solo la estructura de navegación.
- Emite una URL canónica para la página actual y enlaces hreflang recíprocos para cada configuración regional disponible.
- Incluye las URL localizadas en el sitemap y usa x-default como respaldo neutro cuando corresponda.
- Mantén un selector de idioma rastreable y evita redirecciones forzadas que atrapen a usuarios o bots en una sola configuración regional.
Mantén rápidas las páginas localizadas
Los Server Components brindan una oportunidad importante para mejorar el rendimiento: los catálogos que se cargan y consumen exclusivamente en el servidor no tienen que convertirse en JavaScript de cliente. Conserva en el servidor los encabezados de página, las etiquetas de navegación y la mayor parte del texto estático. Cuando un Client Component interactivo necesite mensajes, proporciona solo el espacio de nombres correspondiente o las propiedades ya traducidas, en lugar de serializar todo el catálogo de la configuración regional en cada página.
La generación estática cambia trabajo en el momento de la solicitud por trabajo durante la compilación. Cada configuración regional multiplica el número de variantes de página, así que mide la duración de la compilación y el tamaño de la salida a medida que el sitio crece. Genera con antelación las páginas de mayor valor, divide los catálogos por ruta o dominio y evita importar todos los idiomas desde un módulo de cliente compartido. El objetivo es ofrecer HTML localizado sin obligar a cada visitante a descargar contenido de idiomas que nunca ha seleccionado.
- Carga únicamente la configuración regional activa y los espacios de nombres que requiere la ruta.
- Formatea y traduce en Server Components, salvo que la interacción en el navegador requiera un límite de cliente.
- Genera explícitamente cada configuración regional compatible y supervisa el coste de compilación a medida que crece el conjunto de rutas.
- Mantén una configuración regional determinista para que una misma URL produzca siempre la misma salida estática.
El lugar de Translatable
Una biblioteca de Next.js determina cómo selecciona y renderiza los mensajes la aplicación. Una plataforma de localización aborda el ciclo de vida que los rodea: recopilar claves, traducir valores, revisar cambios, mantener alineados los catálogos de cada configuración regional y distribuir contenido aprobado. Estas necesidades aparecen en cuanto los textos cambian con más frecuencia que los despliegues o los colaboradores dejan de limitarse a un único desarrollador.
Translatable está diseñado en torno a archivos de localización JSON. Los equipos pueden importar catálogos existentes, editarlos o traducirlos con ayuda de la IA, sincronizarlos mediante proveedores de Git y distribuir las actualizaciones a través de una CDN. La aplicación conserva el control de su enrutamiento y su biblioteca de i18n, de modo que la distribución de mensajes pueda evolucionar sin vincular los componentes de vista a un entorno de ejecución propietario.
Empieza con catálogos incluidos en el repositorio y un flujo durante la compilación. Introduce la distribución remota solo cuando agilizar las actualizaciones de texto aporte un valor real y conserva un respaldo integrado para las páginas críticas. Este camino progresivo mantiene determinista el renderizado estático y, a medida que crece el producto, ofrece a los equipos de contenido una vía más limpia hacia producción.
Preguntas frecuentes
¿Qué es mejor para i18n: App Router o Pages Router?
Para aplicaciones nuevas, App Router suele ser el mejor punto de partida, ya que los Server Components pueden cargar mensajes sin enviar catálogos completos al navegador. Pages Router sigue siendo válido para aplicaciones existentes e incluye enrutamiento por configuración regional mediante next.config.js. Elige primero el router que se ajuste a la aplicación y, después, una biblioteca de i18n compatible con él.
¿Debería usar next-intl o next-i18next?
Elige next-intl si buscas una API orientada a ICU y un enrutamiento por configuración regional profundamente integrado. Elige next-i18next si tu equipo prefiere el ecosistema de i18next, sus espacios de nombres y sus complementos; las versiones actuales son compatibles con ambos routers. Un enfoque basado únicamente en diccionarios del framework es adecuado para proyectos pequeños con mensajes sencillos, pero tendrás que aportar tus propias herramientas de formato, extracción, validación y gestión del flujo de trabajo.
¿App Router de Next.js incluye enrutamiento i18n?
App Router proporciona las primitivas de enrutamiento y renderizado necesarias para la localización, pero no un sistema de mensajes completo. Debes crear un segmento de configuración regional como app/[locale], cargar diccionarios o usar una biblioteca e implementar la negociación si es necesario. Por su parte, Pages Router ofrece enrutamiento por configuración regional integrado mediante el campo i18n de next.config.js.
¿Puede un sitio Next.js localizado usar una exportación estática?
Sí, siempre que todas las rutas localizadas puedan generarse con antelación. Con App Router, usa un segmento [locale] explícito y generateStaticParams. Una exportación puramente estática no puede depender de Proxy, cookies, redirecciones ni detección de idioma en el momento de la solicitud. El enrutamiento i18n integrado de Pages Router no es compatible con output: 'export', por lo que los proyectos de exportación necesitan rutas de configuración regional explícitas.
¿Puedo añadir configuraciones regionales a Next.js sin cambiar el código?
Por lo general, no del todo. Una nueva configuración regional requiere un catálogo, actualizar la configuración de configuraciones regionales compatibles, parámetros estáticos o configuración de enrutamiento, metadatos localizados y una nueva compilación. Una plataforma de traducción puede eliminar gran parte del trabajo manual con los catálogos, pero la aplicación debe seguir reconociendo y publicando la configuración regional de forma segura.
Crea un flujo de localización que tu equipo pueda mantener
Reúne tus catálogos JSON, tradúcelos con ayuda de la IA y distribuye las actualizaciones mediante Git o una CDN global.
Empieza gratis