Internacionaliza un sitio en React o Next.js (next-intl) | We.Inc
Traduce bien un sitio en React o Next.js: archivos de mensajes, rutas por idioma con next-intl, formato con Intl para fechas, dinero y plurales, diseños de derecha a izquierda y etiquetas hreflang.
Guarda todos los textos en un archivo JSON de mensajes por idioma, da a cada idioma su propia URL, como /de/about, y formatea fechas, precios y plurales con las API Intl integradas en el navegador. En el App Router de Next.js, next-intl une todas estas piezas: un segmento de ruta [locale], un proxy que elige el idioma y useTranslations en los componentes.
Las partes de un sitio traducido
Parte
Qué usar
Textos
messages/en.json, messages/de.json, etc.
URLs
Un prefijo de ruta por idioma: /en/..., /de/...
Detección del idioma
createMiddleware de next-intl en proxy.ts (middleware.ts antes de Next.js 16)
Fechas, números, dinero
Intl.DateTimeFormat e Intl.NumberFormat
Plurales
Sintaxis de mensajes ICU o Intl.PluralRules
Buscadores
Enlaces hreflang para cada versión de idioma, más x-default
Traducir es más que cambiar palabras. El orden de las palabras cambia, las reglas de plural son distintas, el árabe se lee de derecha a izquierda y cada país escribe las fechas a su manera. Prueba el selector de abajo para ver cómo una pequeña tarjeta de producto cambia de idioma y luego construye lo mismo en tu app con los archivos de configuración y el generador de hreflang.
Elige un idioma en la demo. La tarjeta cambia sus mensajes, formatea el precio y la fecha para ese idioma e invierte la dirección para el árabe.
Cambia la cantidad de artículos para ver cómo cada idioma elige su propia forma de plural.
Copia los archivos de configuración de next-intl en un proyecto de Next.js con App Router.
Escribe tu dominio y tus idiomas en el generador de hreflang y pega las etiquetas, o el objeto de metadata, en tu layout.
Nunca construyas frases uniendo fragmentos. Traduce frases completas con marcadores como {count}, porque el orden de las palabras varía.
Deja espacio en tu diseño, porque una etiqueta traducida suele ser bastante más larga que la inglesa.
Define lang en el elemento html para cada idioma y dir="rtl" para los de derecha a izquierda.
Evita las banderas en los selectores de idioma. Las banderas representan países, y muchos idiomas se hablan en varios.
Deja que la gente cambie de idioma manualmente y recuerda su elección en lugar de depender solo de la configuración del navegador.
Preguntas frecuentes
¿Qué biblioteca de i18n debo usar con React?
Para el App Router de Next.js, next-intl está hecha a propósito y admite Server Components. Para una app de React sin Next.js, elige una biblioteca que guarde los mensajes como JSON, así migrar más adelante a otra seguirá siendo manejable.
¿Los idiomas deben ir en subcarpetas, subdominios o dominios separados?
Las subcarpetas como example.com/de/ son lo más sencillo de mantener, porque un solo sitio y un solo dominio lo llevan todo. next-intl también admite rutas por dominio si necesitas de.example.com o un dominio de país.
¿Cómo añado hreflang en Next.js?
Devuelve alternates.languages desde metadata o generateMetadata, con una entrada por cada URL de idioma. Next.js imprime una etiqueta link rel="alternate" hreflang para cada una. Cada versión de idioma debe enumerar todas las demás y a sí misma, o los buscadores pueden ignorar el conjunto.
¿Puedo traducir mi sitio con traducción automática?
Puedes usar la traducción automática como primer borrador, pero haz que la revise un hablante con fluidez, sobre todo los titulares, los precios y los textos legales. Las traducciones pobres o sin revisar pueden confundir a los lectores y restar confianza.
Mensajes, no textos dentro de los componentes
Cada texto que ve una persona debería venir de un archivo de mensajes con claves según su significado, como Cart.checkoutButton. Los desarrolladores editan el inglés, los traductores editan los demás archivos y nadie tiene que rebuscar en los componentes textos escritos a mano.
Separar por espacios de nombres según el componente mantiene los archivos legibles. Así, useTranslations('Cart') de next-intl te da t('checkoutButton') solo dentro de ese componente.
Deja que Intl se encargue del formato
Intl.NumberFormat escribe 1234.5 euros como 1.234,50 € para un lector alemán, con el símbolo y los separadores colocados como espera ese idioma. Intl.DateTimeFormat hace lo mismo con las fechas, e Intl.PluralRules te dice si un número usa la forma one, few, many u other en un idioma concreto.
Estas API vienen incluidas en todos los navegadores modernos y en Node, así que el formato no añade peso a tu bundle y sigue siendo correcto para idiomas que nunca has estudiado.
Idiomas de derecha a izquierda
El árabe, el hebreo, el persa y el urdu se leen de derecha a izquierda. Definir dir="rtl" en el elemento html refleja la alineación del texto y el orden del contenido en línea, pero los valores fijos de left y right en el CSS se quedan donde están.
Usa propiedades lógicas como margin-inline-start y padding-inline-end, o las utilidades ms- y pe- de Tailwind, para que el espaciado se invierta automáticamente con la dirección.
Configuración de next-intl para el App Router
Instálalo con npm install next-intl. Estos archivos siguen la estructura de la propia guía de inicio de next-intl para rutas basadas en el idioma.
Un archivo por idioma, con las mismas claves en cada uno. La sintaxis ICU gestiona los plurales dentro del mensaje.
src/i18n/routing.ts y src/proxy.ts
Routing enumera tus idiomas una sola vez. El proxy (llamado middleware.ts antes de Next.js 16) redirige a los visitantes a un prefijo de idioma.
src/i18n/request.ts
Lee el idioma del segmento [locale], rechaza los desconocidos y carga los mensajes de ese idioma.
next.config.ts, layout y una página
El plugin enlaza request.ts. Mueve tus páginas bajo app/[locale]/ y lee los mensajes con useTranslations. next/root-params está activado por defecto desde Next.js 16.3; las versiones anteriores necesitan experimental.rootParams.
Formato sin biblioteca
Intl en JavaScript puro
Funciona en cualquier app de React, esté traducida o no.
Reglas de hreflang que comprueban los buscadores
Cómo hacer bien las anotaciones de idioma
Regla
Ejemplo
Usa URLs absolutas completas
Cada versión se enumera a sí misma y a todas las demás
La página en alemán enlaza a en, de, ar y x-default
El idioma va en ISO 639-1, con región opcional en ISO 3166-1 alpha-2
de, en-GB, pt-BR
Nunca una región sola
be es bielorruso, no Bélgica; usa nl-BE o fr-BE
x-default para todos los demás
Apunta a un selector de idioma o a tu versión principal
Pruébalo: una tarjeta en cinco idiomas
Cambia de idioma y modifica la cantidad de artículos. Los textos vienen de un objeto de mensajes, y el precio, la fecha y la forma de plural vienen de las API Intl del navegador.
Idioma
Artículos en el carrito: {n}
Categoría de plural elegida:
Dirección:
La demo no convierte divisas; solo formatea el mismo número.
Generador de hreflang
Escribe tu dominio, la ruta de una página y tus códigos de idioma para obtener las etiquetas link para el head, o el objeto alternates de Next.js.
Dominio
Ruta de la página
Códigos de idioma (separados por comas)
Idioma x-default
Códigos no válidos omitidos: {codes}. Usa un formato como de o en-GB.