Cómo implementar internacionalización en Next.js
Ejemplos
Next.js tiene soporte integrado para enrutamiento internacionalizado (i18n) desde la versión v10.0.0
. Puedes proporcionar una lista de locales, el locale predeterminado y locales específicos de dominio, y Next.js manejará automáticamente el enrutamiento.
El soporte de enrutamiento i18n actualmente está diseñado para complementar soluciones existentes de bibliotecas i18n como react-intl
, react-i18next
, lingui
, rosetta
, next-intl
, next-translate
, next-multilingual
, tolgee
, paraglide-next
, next-intlayer
y otras, simplificando las rutas y el análisis de locales.
Primeros pasos
Para comenzar, agrega la configuración i18n
a tu archivo next.config.js
.
Los locales son Identificadores de Locale UTS, un formato estandarizado para definir locales.
Generalmente, un Identificador de Locale está compuesto por un idioma, región y script separados por un guión: idioma-region-script
. La región y el script son opcionales. Un ejemplo:
en-US
- Inglés como se habla en Estados Unidosnl-NL
- Holandés como se habla en los Países Bajosnl
- Holandés, sin región específica
Si el locale del usuario es nl-BE
y no está listado en tu configuración, se redirigirá a nl
si está disponible, o al locale predeterminado en caso contrario.
Si no planeas admitir todas las regiones de un país, es una buena práctica incluir locales de país que actuarán como respaldo.
Estrategias de Locale
Hay dos estrategias para manejar locales: Enrutamiento por Sub-ruta y Enrutamiento por Dominio.
Enrutamiento por Sub-ruta
El Enrutamiento por Sub-ruta coloca el locale en la ruta de la URL.
Con la configuración anterior en-US
, fr
y nl-NL
estarán disponibles para enrutar, y en-US
es el locale predeterminado. Si tienes un pages/blog.js
, las siguientes URLs estarán disponibles:
/blog
/fr/blog
/nl-nl/blog
El locale predeterminado no tiene prefijo.
Enrutamiento por Dominio
Al usar el enrutamiento por dominio, puedes configurar locales para ser servidos desde diferentes dominios:
Por ejemplo, si tienes pages/blog.js
, las siguientes URLs estarán disponibles:
example.com/blog
www.example.com/blog
example.fr/blog
example.nl/blog
example.nl/nl-BE/blog
Detección Automática de Locale
Cuando un usuario visita la raíz de la aplicación (generalmente /
), Next.js intentará detectar automáticamente qué locale prefiere el usuario basándose en el encabezado Accept-Language
y el dominio actual.
Si se detecta un locale diferente al predeterminado, el usuario será redirigido a:
- Con Enrutamiento por Sub-ruta: La ruta con prefijo de locale
- Con Enrutamiento por Dominio: El dominio con ese locale especificado como predeterminado
Con Enrutamiento por Dominio, si un usuario con el encabezado Accept-Language
fr;q=0.9
visita example.com
, será redirigido a example.fr
ya que ese dominio maneja el locale fr
por defecto.
Con Enrutamiento por Sub-ruta, el usuario sería redirigido a /fr
.
Prefijar el Locale Predeterminado
Con Next.js 12 y Middleware, podemos agregar un prefijo al locale predeterminado con una solución alternativa.
Por ejemplo, aquí hay un archivo next.config.js
con soporte para algunos idiomas. Nota que el locale "default"
se ha agregado intencionalmente.
Luego, podemos usar Middleware para agregar reglas de enrutamiento personalizadas:
Este Middleware omite agregar el prefijo predeterminado a API Routes y archivos públicos como fuentes o imágenes. Si se hace una solicitud al locale predeterminado, redirigimos a nuestro prefijo /en
.
Desactivar la Detección Automática de Locale
La detección automática de locale se puede desactivar con:
Cuando localeDetection
está configurado como false
, Next.js ya no redirigirá automáticamente basándose en el locale preferido del usuario y solo proporcionará información de locale detectada desde el dominio basado en locale o la ruta de locale como se describió anteriormente.
Accediendo a la información del locale
Puedes acceder a la información del locale a través del enrutador de Next.js. Por ejemplo, usando el hook useRouter()
están disponibles las siguientes propiedades:
locale
contiene el locale actualmente activo.locales
contiene todos los locales configurados.defaultLocale
contiene el locale predeterminado configurado.
Al pre-renderizar páginas con getStaticProps
o getServerSideProps
, la información del locale se proporciona en el contexto proporcionado a la función.
Al aprovechar getStaticPaths
, los locales configurados se proporcionan en el parámetro de contexto de la función bajo locales
y el defaultLocale
configurado bajo defaultLocale
.
Transición entre locales
Puedes usar next/link
o next/router
para transicionar entre locales.
Para next/link
, se puede proporcionar una propiedad locale
para transicionar a un locale diferente del actualmente activo. Si no se proporciona ninguna propiedad locale
, se usará el locale
actualmente activo durante las transiciones del cliente. Por ejemplo:
Cuando usas los métodos de next/router
directamente, puedes especificar el locale
que debe usarse a través de las opciones de transición. Por ejemplo:
Nota que para manejar el cambio solo del locale
manteniendo toda la información de enrutamiento como valores de consulta de rutas dinámicas o valores de consulta href ocultos, puedes proporcionar el parámetro href
como un objeto:
Consulta aquí para más información sobre la estructura del objeto para router.push
.
Si tienes un href
que ya incluye el locale, puedes optar por no manejar automáticamente el prefijo de locale:
Aprovechando la cookie NEXT_LOCALE
Next.js permite configurar una cookie NEXT_LOCALE=el-locale
, que tiene prioridad sobre el encabezado accept-language. Esta cookie se puede configurar usando un selector de idioma y luego, cuando un usuario regresa al sitio, aprovechará el locale especificado en la cookie al redirigir desde /
a la ubicación correcta del locale.
Por ejemplo, si un usuario prefiere el locale fr
en su encabezado accept-language pero se ha configurado una cookie NEXT_LOCALE=en
, al visitar /
el usuario será redirigido a la ubicación del locale en
hasta que la cookie se elimine o expire.
Optimización para Motores de Búsqueda
Como Next.js sabe qué idioma está visitando el usuario, agregará automáticamente el atributo lang
a la etiqueta <html>
.
Next.js no sabe sobre las variantes de una página, por lo que depende de ti agregar las etiquetas meta hreflang
usando next/head
. Puedes aprender más sobre hreflang
en la documentación de Google Webmasters.
¿Cómo funciona esto con Generación Estática?
Nota que el Enrutamiento Internacionalizado no se integra con
output: 'export'
ya que no aprovecha la capa de enrutamiento de Next.js. Las aplicaciones híbridas de Next.js que no usanoutput: 'export'
son totalmente compatibles.
Rutas Dinámicas y Páginas getStaticProps
Para páginas que usan getStaticProps
con Rutas Dinámicas, todas las variantes de locale de la página que se desean prerrenderizar deben devolverse desde getStaticPaths
. Junto con el objeto params
devuelto para paths
, también puedes devolver un campo locale
especificando qué locale deseas renderizar. Por ejemplo:
Para páginas Optimizadas Estáticamente de Forma Automática y páginas no dinámicas con getStaticProps
, se generará una versión de la página para cada locale. Esto es importante considerarlo porque puede aumentar los tiempos de construcción dependiendo de cuántos locales estén configurados dentro de getStaticProps
.
Por ejemplo, si tienes 50 locales configurados con 10 páginas no dinámicas que usan getStaticProps
, esto significa que getStaticProps
se llamará 500 veces. Se generarán 50 versiones de las 10 páginas durante cada construcción.
Para disminuir el tiempo de construcción de páginas dinámicas con getStaticProps
, usa un modo fallback
. Esto te permite devolver solo las rutas y locales más populares desde getStaticPaths
para prerrenderizar durante la construcción. Luego, Next.js construirá las páginas restantes en tiempo de ejecución a medida que se soliciten.
Páginas Optimizadas Estáticamente de Forma Automática
Para páginas que están optimizadas estáticamente de forma automática, se generará una versión de la página para cada locale.
Páginas No Dinámicas con getStaticProps
Para páginas no dinámicas con getStaticProps
, se genera una versión para cada locale como se mencionó anteriormente. getStaticProps
se llama con cada locale
que se está renderizando. Si deseas excluir un cierto locale de ser prerrenderizado, puedes devolver notFound: true
desde getStaticProps
y esa variante de la página no se generará.
Límites para la configuración i18n
locales
: 100 locales en totaldomains
: 100 elementos de dominio de locale en total
Nota importante: Estos límites se agregaron inicialmente para evitar posibles problemas de rendimiento en tiempo de construcción. Puedes solucionar estos límites con enrutamiento personalizado usando Middleware en Next.js 12.