Haz tu pregunta y obtén un resumen del documento referenciando esta página y el proveedor AI de tu elección
Historial de versiones
- "Versión inicial"v9.5.1026/9/2026
El contenido de esta página ha sido traducido con una IA.
Ver la última versión del contenido original en inglésSi tienes una idea para mejorar esta documentación, no dudes en contribuir enviando una pull request en GitHub.
Enlace de GitHub a la documentaciónCopiar el Markdown del documento a la portapapeles
Cómo internacionalizar tu aplicación Next.js con Lingui en 2026
Tabla de contenidos
¿Qué es Lingui?
Lingui es una librería de i18n construida alrededor de macros y extracción de mensajes. Escribes el texto fuente directamente en tus componentes ( t`Hello` , <Trans>Hello</Trans>), lingui extract recopila cada mensaje en catálogos (archivos PO por defecto) y un loader los compila a JavaScript compacto. Los mensajes utilizan ICU MessageFormat, y Lingui es compatible con React Server Components en el App Router.
Esta guía configura Lingui en un proyecto con Next.js 16 App Router, incluyendo:
- Macros compiladas por SWC, para que Turbopack mantenga su velocidad.
- Server y Client Components compartiendo la misma API de
TransyuseLingui. - Enrutamiento de idiomas a través de
proxy.ts:/aboutpara el idioma predeterminado,/fr/aboutpara los demás y detección de idioma en la primera visita. - Renderizado estático de cada idioma con
generateStaticParams. - SEO multilingüe completo:
generateMetadatatraducido, canonical,hreflangconx-default, locales de Open Graph, JSON-LD,sitemap.ts,robots.tsy páginas 404 localizadas.
¿Buscas otra librería? Consulta la guía de next-intl, la guía de next-i18next o la guía de Next.js + Intlayer.
¿Usas TanStack Start? Consulta la guía de TanStack Start + Lingui. ¿Comparando librerías? Lee Lingui vs Intlayer y next-i18next vs next-intl vs Intlayer.
Qué dice el benchmark sobre Lingui en Next.js
El benchmark de i18n ejecuta la misma aplicación Next.js de 10 páginas y 10 idiomas con cada una de las librerías principales y mide lo que el navegador descarga realmente.
Carga JSON dinámica
Carga traducciones en tiempo de ejecución
JSON con alcance (namespacing)
Espacios de nombres de traduction por página
Benchmark de Rendimiento I18n
¿Qué es esta métrica?
El tamaño total comprimido en gzip del paquete de la biblioteca de internacionalización. Solo incluye el proveedor y la lógica de recuperación de contenido después del tree-shaking y la minificación.
¿Por qué es importante?
Un tamaño de biblioteca más pequeño reduce la carga útil inicial de JavaScript, lo que acelera el tiempo de descarga y ejecución en el cliente.
Ver como
Cifras clave para @lingui/core@6.6.0 en Next.js 16, medidas el 2026-09-26 (gzip):
Abrir la tabla en una ventana flotante para ver todo el contenido claramente
| Configuración | Tamaño de librería | JS por página | Fuga de otros idiomas | Fuga de otras páginas |
|---|---|---|---|---|
| Sin i18n (app base) | - | 141.0 KB | 0% | 0% |
| Lingui, un catálogo por idioma | 72.1 KB | 145.4 KB | 2.8% | 89.9% |
@intlayer/lingui (compat) | 10.7 KB | 221.6 KB | 50% | 90% |
next-intlayer (Intlayer nativo) | 4.9 KB | 141.5 KB | 0% | 0% |
Conclusiones principales:
- Un único catálogo por idioma aún filtra mensajes de otras páginas al proveedor de cliente. Mantén la mayor cantidad de texto posible en Server Components, que envían HTML renderizado en lugar de catálogos.
- El runtime de Lingui pesa ~72 KB gzip. El adaptador de compatibilidad
@intlayer/linguireduce el runtime a ~11 KB, pero en este benchmark la configuración de compatibilidad con Next.js todavía envía catálogos completos a la página. La API nativa denext-intlayeres la configuración que se mantiene en el tamaño de la aplicación base.
Consulta todos los datos: informe del benchmark de Next.js y el repositorio del benchmark.
Comparación de características en Next.js
Cómo se compara Lingui con next-intl e Intlayer en las funcionalidades que suele requerir un proyecto con Next.js App Router:
Abrir la tabla en una ventana flotante para ver todo el contenido claramente
| Característica | next-intlayer (Intlayer) | Lingui | next-intl |
|---|---|---|---|
| Traducciones junto a componentes | ✅ Contenido coubicado con cada componente | ⚠️ Texto fuente en componentes, catálogos centralizados | ❌ JSON centralizado |
| Integración con TypeScript | ✅ Tipos estrictos autogenerados | ⚠️ Macros tipadas, catálogos de mensajes no | ✅ Buena, mediante aumento de AppConfig |
| Detección de traducciones faltantes | ✅ Errores de TypeScript y advertencias en compilación | ⚠️ Fallback en tiempo de ejecución al texto fuente | ⚠️ Fallback en tiempo de ejecución |
| Contenido enriquecido (JSX, Markdown) | ✅ Soporte directo | ✅ JSX dentro de <Trans>, sin Markdown | ⚠️ Etiquetas vía t.rich, sin Markdown |
| Traducción con IA | ✅ Tu propio proveedor y clave de API, con contexto de app | ❌ No | ❌ No |
| Editor visual / CMS | ✅ Editor visual local + CMS opcional | ❌ Mediante plataformas externas | ❌ Mediante plataformas externas |
| Enrutamiento localizado | ✅ Integrado | ❌ Escribe tu propio proxy.ts | ✅ Segmento [locale] integrado |
| Pluralización | ✅ Basada en enumeración | ✅ ICU, macro <Plural> | ✅ ICU |
| Formatos de contenido | ✅ .ts, .tsx, .js, .json, .md, .yaml | ✅ PO, JSON, CSV | ✅ .json, .js, .ts |
| ICU MessageFormat | ✅ Mediante format: "icu" | ✅ Nativo | ✅ Nativo |
| Ayudantes SEO (hreflang, sitemap) | ✅ Ayudantes para metadatos, sitemap y robots.txt | ❌ Manual | ✅ Bueno |
| Server Components | ✅ Acceso directo en cualquier Server Component | ⚠️ setI18n en cada layout y página | ⚠️ await getTranslations() por componente |
| Tree-shaking por componente | ✅ En tiempo de compilación (Babel / SWC) | ⚠️ Un catálogo por idioma, extractor por página experimental | ⚠️ Manual, con pick() por ruta |
| Tamaño de runtime (gzip, benchmark) | 4.9 KB | 72.1 KB | 14.7 KB |
| Traducciones faltantes en CI | ✅ npx intlayer test | ✅ lingui compile --strict | ⚠️ No integrado |
| Ecosistema / comunidad | ⚠️ Más pequeño, crecimiento rápido | ✅ Maduro | ✅ Grande |
Los tamaños de runtime provienen del benchmark de Next.js. Para un análisis detallado, consulta Lingui vs Intlayer.
Otras guías de Next.js: next-intl, next-i18next e Intlayer.
Buenas prácticas recomendadas
- Define
langydiren<html>dentro del layout[locale]. - Prefiere Server Components para el texto: renderizan HTML en el servidor y no necesitan el catálogo en el cliente.
- Llama a
initLingui(locale)en cada layout y página. Los layouts no se vuelven a renderizar durante la navegación, por lo que una página no puede asumir que su layout ha establecido el idioma. - Mantén una URL por idioma y pre-renderiza cada idioma con
generateStaticParams. - Traduce tus metadatos en
generateMetadata, incluyendocanonical,hreflangyx-default. - Genera un sitemap y robots.txt multilingües usando las convenciones
sitemap.tsyrobots.ts. - Usa enlaces reales para el selector de idioma, para que los motores de búsqueda descubran cada versión lingüística.
- Ejecuta
lingui extracten CI para que ningún mensaje nuevo se envíe sin traducir.
Consulta nuestra guía sobre internacionalización y SEO, la guía de hreflang y la comparativa de SEO multilingüe en Next.js.
Guía paso a paso para configurar Lingui en una aplicación Next.js
Esta es la estructura del proyecto que crearemos:
Copiar el código al portapapeles
Instalar dependencias
bashCopiar códigoCopiar el código al portapapeles
- @lingui/core / @lingui/react: runtime,
I18nProvider,setI18npara Server Components y las macros (@lingui/core/macro,@lingui/react/macro). - @lingui/swc-plugin: compila las macros dentro del pipeline de SWC en Next.js.
- @lingui/loader: compila catálogos
.poal importarlos, eliminando la necesidad delingui compile. - @lingui/cli:
lingui extractpara recopilar mensajes en catálogos.
@lingui/swc-plugines un plugin WebAssembly vinculado a la versión de SWC de Next.js. Si la compilación falla tras actualizar Next.js, actualiza el plugin a la versión indicada como compatible en su README.- @lingui/core / @lingui/react: runtime,
Centralizar la configuración de idiomas
Un solo archivo define los idiomas y los ayudantes de URL. El enrutamiento, los metadatos, el sitemap y Lingui leen todos de él.
src/i18n/config.tsCopiar códigoCopiar el código al portapapeles
Configurar Lingui y Next.js
lingui.config.tsCopiar códigoCopiar el código al portapapeles
El plugin de SWC compila las macros y el loader compila los archivos
.po, tanto para Turbopack (predeterminado en Next.js 16) como para webpack:next.config.tsCopiar códigoCopiar el código al portapapeles
Agrega los scripts de extracción:
package.jsonCopiar códigoCopiar el código al portapapeles
Cargar catálogos y crear instancias del servidor
Los Server Components no tienen contexto de React, por lo que Lingui proporciona
setI18npara registrar la instancia para el render actual. Este módulo carga cada catálogo una vez por proceso de servidor y crea una instancia deI18npor idioma. Esserver-only: los catálogos de otros idiomas nunca llegan al bundle del cliente.src/i18n/appRouterI18n.tsCopiar códigoCopiar el código al portapapeles
src/i18n/initLingui.tsCopiar códigoCopiar el código al portapapeles
Para que TypeScript reconozca la importación de archivos
.po, declara el módulo una vez:src/i18n/po.d.tsCopiar códigoCopiar el código al portapapeles
Crear el proveedor del cliente
Los Client Components leen las traducciones desde un contexto de React. El proveedor recibe el catálogo del idioma activo desde el layout del servidor y crea su propia instancia una sola vez.
src/components/LinguiClientProvider.tsxCopiar códigoCopiar el código al portapapeles
Definir rutas de idioma dinámicas
El segmento
[locale]contiene el layout raíz.generateStaticParamspre-renderiza cada idioma en tiempo de compilación, ydynamicParams = falsedevuelve un 404 para cualquier otro prefijo.src/app/[locale]/layout.tsxCopiar códigoCopiar el código al portapapeles
El proveedor de cliente recibe el catálogo completo del idioma activo. Esto es lo que el benchmark mide como "fuga de otras páginas". Mantener el texto en Server Components limita lo que el cliente realmente necesita. Para aplicaciones grandes, el extractor por página experimental de Lingui (
experimental.extractorenlingui.config.ts) divide los catálogos por punto de entrada.Utilizar traducciones en Server Components
Los Server Components utilizan las mismas macros que los Client Components.
initLinguidebe ejecutarse también en la página, ya que un layout no se vuelve a renderizar al navegar entre sus páginas.src/app/[locale]/about/page.tsxCopiar códigoCopiar el código al portapapeles
Utilizar traducciones en Client Components
Los Client Components utilizan las mismas importaciones. Las macros leen la instancia desde
LinguiClientProvider.src/components/Counter.tsxCopiar códigoCopiar el código al portapapeles
Extraer y traducir tus mensajes
Ejecuta la extracción. Lingui escribe cada mensaje encontrado en
srcen el catálogo de cada idioma:bashCopiar códigoCopiar el código al portapapeles
Luego traduce el
msgstrde cada entrada:src/locales/fr/messages.poCopiar códigoCopiar el código al portapapeles
src/locales/es/messages.poCopiar códigoCopiar el código al portapapeles
Los marcadores de posición
<0>conservan los elementos JSX de un<Trans>en su lugar, de modo que los traductores puedan moverlos sin modificar el marcado.Configurar el proxy para el enrutamiento de idiomas
OpcionalNext.js 16 renombró
middleware.tsaproxy.ts. El proxy implementa la estrategia de prefijo según necesidad ("as-needed"):/fr/aboutse sirve tal cual;/en/aboutredirige a/about, para que el idioma predeterminado tenga una única URL;/aboutse reescribe internamente a/en/about, sin cambiar la URL visible;- una primera visita en
/redirige al idioma de preferencia (primero cookie, luegoAccept-Language).
src/i18n/negotiateLocale.tsCopiar códigoCopiar el código al portapapeles
src/proxy.tsCopiar códigoCopiar el código al portapapeles
Cambiar el idioma de tu contenido
OpcionalusePathnamedevuelve la URL que ve el navegador (/abouto/fr/about). Elimina el prefijo de idioma y luego construye el enlace de cada lengua. El selector genera enlaces reales para que los rastreadores puedan acceder a todas las versiones lingüísticas, y la cookie recuerda la elección explícita.src/components/LocaleSwitcher.tsxCopiar códigoCopiar el código al portapapeles
Construir un componente de enlace localizado
Opcionalsrc/components/LocalizedLink.tsxCopiar códigoCopiar el código al portapapeles
También funciona desde Server Components, ya que se renderiza dentro de
LinguiClientProvider:tsxCopiar códigoCopiar el código al portapapeles
Internacionalizar tus metadatos
OpcionalCada versión idiomática puede posicionarse por sí misma, siempre que cada página incluya:
- un
titleydescriptiontraducidos; - una URL canonical apuntando a sí misma;
- una alternativa
hreflangpor cada idioma, además dex-default; locale,alternateLocaleyurlpara Open Graph;- JSON-LD con
inLanguage.
generateMetadatase ejecuta fuera del árbol de React, por lo que utiliza la instancia del servidor directamente con la macromsg:src/i18n/metadata.tsCopiar códigoCopiar el código al portapapeles
src/app/[locale]/about/page.tsxCopiar códigoCopiar el código al portapapeles
JSON-LD es renderizado directamente por la página. Los archivos de página solo deben exportar campos reconocidos por Next.js, por lo que conviene mantener el componente en su propio archivo:
src/components/WebPageJsonLd.tsxCopiar códigoCopiar el código al portapapeles
src/app/[locale]/about/page.tsxCopiar códigoCopiar el código al portapapeles
- un
Internacionalizar tu sitemap
OpcionalLa convención
sitemap.tsadmitealternates.languages, que Next.js renderiza como alternativasxhtml:link. Incluye cada URL de cada idioma:src/app/sitemap.tsCopiar códigoCopiar el código al portapapeles
Internacionalizar tu robots.txt
OpcionalLas rutas privadas existen en todos los idiomas, por lo que
disallowdebe cubrir cada ruta localizada:src/app/robots.tsCopiar códigoCopiar el código al portapapeles
Gestionar páginas 404 localizadas
Opcionalnot-found.tsxse renderiza dentro del layout[locale], por lo que tiene acceso al proveedor de cliente. La ruta comodín ("catch-all") le redirige las rutas desconocidas dentro de un idioma. Next.js añade automáticamentenoindexa las respuestas 404.src/app/[locale]/not-found.tsxCopiar códigoCopiar el código al portapapeles
src/app/[locale]/[...rest]/page.tsxCopiar códigoCopiar el código al portapapeles
Acceder al idioma en Server Actions
OpcionalLas Server Actions no reciben parámetros de ruta. El enfoque más confiable es enviar el idioma junto con el formulario, desde la página que lo conoce:
src/app/[locale]/contact/page.tsxCopiar códigoCopiar el código al portapapeles
src/app/actions/sendContactMessage.tsCopiar códigoCopiar el código al portapapeles
Mantén tus macros, reduce el runtime con Intlayer
OpcionalEl adaptador de compatibilidad
@intlayer/linguimantiene tu código fuente intacto: las macros se compilan como antes y las llamadas resultantes ai18n._(),useLingui()y<Trans>son atendidas por diccionarios de Intlayer. En el benchmark de Next.js, el runtime disminuye de ~72.1 KB a ~10.7 KB gzip.En Next.js, el adaptador se integra creando alias de
@lingui/corey@lingui/reacthacia@intlayer/linguiennext.config.ts(webpack y Turbopack), y envolviendo la configuración conwithIntlayerdenext-intlayer/server. Mantén@lingui/swc-pluginpara que las macros sigan compilándose en primer lugar. La configuración completa se encuentra en la guía de compatibilidad con Lingui.Como muestra la tabla de benchmark, el adaptador reduce el tamaño del runtime, aunque en Next.js aún no reduce el catálogo enviado a cada página. Resulta ideal como puente de migración: una vez en funcionamiento, puedes migrar componentes uno a uno a la API nativa de
useIntlayer, que envía únicamente el contenido que cada componente renderiza. Consulta la guía de Next.js + Intlayer, Lingui vs @intlayer/lingui y todos los adaptadores de compatibilidad.Automatiza tus traducciones con Intlayer
OpcionalLingui extrae los mensajes, pero rellenar decenas de catálogos a mano es donde se va la mayor parte del tiempo. Intlayer es gratuito y de código abierto, y sus herramientas funcionan junto a Lingui:
- Traduce con IA utilizando tu propia clave de API y proveedor. Consulta autocompletado y el CLI.
- Conserva tus archivos PO como fuente de verdad con el plugin de sincronización PO.
- Prueba traducciones faltantes en CI. Consulta pruebas de traducciones.
- Audita tu sitio en producción en busca de
hreflangfaltantes, canonicals incorrectos y fugas de idioma con el comando scan.
Preguntas frecuentes
Sí. @lingui/react es compatible con React Server Components. Los Server Components registran la instancia con setI18n desde @lingui/react/server, los Client Components la leen desde I18nProvider, y ambos utilizan las mismas macros Trans y useLingui.
Los Server Components no disponen de contexto, por lo que la instancia se registra por cada renderizado. Los layouts se preservan entre navegaciones y no se vuelven a renderizar, así que una página no puede depender de que su layout haya configurado el idioma. Llamar a initLingui(locale) al inicio de cada layout y página los mantiene independientes.
Utiliza @lingui/swc-plugin. Mantiene el pipeline de SWC y Turbopack activos. Añadir una configuración de Babel deshabilita SWC en Next.js y ralentiza las compilaciones. La única restricción es mantener la versión del plugin compatible con la versión de SWC de tu versión de Next.js.
Obtén la instancia del servidor con getI18nInstance(locale) y traduce descriptores declarados con la macro msg: i18n._(msg`About us`). Devuelve alternates.canonical, alternates.languages con x-default, y openGraph.locale. El paso 13 incluye una utilidad reutilizable.
El benchmark mide ~72 KB gzip para el runtime. Con un catálogo por idioma, las páginas pesan ~145 KB frente a 141 KB sin i18n, pero cada página aún recibe los mensajes de otras páginas a través del proveedor de cliente.
Lingui se adapta a equipos que prefieren escribir el texto fuente en los componentes y trabajar con archivos PO y traductores. next-intl es ideal para equipos que prefieren catálogos JSON y una API t("clave") estrechamente integrada con Next.js. next-i18next ofrece el ecosistema de plugins de i18next. Consulta next-i18next vs next-intl vs Intlayer y el benchmark de Next.js.
Comentarios
Aún no hay comentarios. Sé el primero en compartir tus pensamientos.
