Recibe notificaciones sobre los próximos lanzamientos de Intlayer
    Creación:2026-01-10Última actualización:2026-01-10

    Traduce tu sitio web Next.js 16 (sin [locale] en la ruta de la página) usando Intlayer | Internacionalización (i18n)

    Ver Plantilla de aplicación en GitHub.

    Tabla de contenidos

    ¿Qué es Intlayer?

    Intlayer es una librería innovadora y de código abierto para internacionalización (i18n) diseñada para simplificar el soporte multilingüe en aplicaciones web modernas. Intlayer se integra sin problemas con el más reciente framework Next.js 16, incluyendo su potente App Router. Está optimizada para funcionar con Server Components para un renderizado eficiente y es completamente compatible con Turbopack.

    Con Intlayer, puedes:

    • Gestionar fácilmente las traducciones usando diccionarios declarativos a nivel de componente.
    • Localizar dinámicamente metadatos, rutas y contenido.
    • Acceder a las traducciones tanto en componentes del lado del cliente como del lado del servidor.
    • Asegurar soporte TypeScript con tipos autogenerados, mejorando el autocompletado y la detección de errores.
    • Aprovecha funciones avanzadas, como la detección dinámica de locales y el cambio entre ellos.
    Intlayer es compatible con Next.js 12, 13, 14 y 16. Si estás usando el Next.js Page Router, puedes consultar esta guía. Para Next.js 12, 13 y 14 con App Router, consulta esta guía.

    Guía paso a paso para configurar Intlayer en una aplicación Next.js

    Paso 1: Instalar dependencias

    Instala los paquetes necesarios usando npm:

    bash
    npm install intlayer next-intlayernpx intlayer init
    • intlayer

      El paquete central que proporciona herramientas de internacionalización para la gestión de configuración, traducción, declaración de contenido, transpilación y comandos CLI.

    • next-intlayer

    El paquete que integra Intlayer con Next.js. Proporciona proveedores de contexto y hooks para la internacionalización en Next.js. Además, incluye el plugin de Next.js para integrar Intlayer con Webpack o Turbopack, así como un proxy para detectar la locale preferida del usuario, gestionar cookies y manejar la redirección de URL.

    Paso 2: Configura tu proyecto

    Aquí está la estructura final que crearemos:

    .├── src│   ├── app│   │   ├── layout.tsx│   │   ├── page.content.ts│   │   └── page.tsx│   ├── components│   │   ├── clientComponentExample│   │   │   ├── client-component-example.content.ts│   │   │   └── ClientComponentExample.tsx│   │   ├── localeSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   └── serverComponentExample│   │       ├── server-component-example.content.ts│   │       └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
    Si no quieres locale routing, intlayer puede usarse como un simple provider / hook. Consulta esta guía para más detalles.

    Crea un archivo de configuración para definir los idiomas de tu aplicación:

    intlayer.config.ts
    import { Locales, type IntlayerConfig } from "intlayer";const config: IntlayerConfig = {  internationalization: {    locales: [      Locales.ENGLISH,      Locales.FRENCH,      Locales.SPANISH,      // Tus otros locales    ],    defaultLocale: Locales.ENGLISH,  },  routing: {    mode: "search-params", // o `no-prefix` - Útil para la detección en el middleware  },};export default config;
    A través de este archivo de configuración, puedes configurar URLs localizadas, redirección de proxy, nombres de cookies, la ubicación y extensión de tus declaraciones de contenido, desactivar los logs de Intlayer en la consola y más. Para una lista completa de los parámetros disponibles, consulta la documentación de configuración.

    Paso 3: Integrar Intlayer en tu configuración de Next.js

    Configura tu setup de Next.js para usar Intlayer:

    next.config.ts
    import type { NextConfig } from "next";import { withIntlayer } from "next-intlayer/server";const nextConfig: NextConfig = {  /* opciones de configuración aquí */};export default withIntlayer(nextConfig);
    El plugin de Next.js withIntlayer() se utiliza para integrar Intlayer con Next.js. Asegura la generación de los archivos de declaración de contenido y los vigila en modo de desarrollo. Define las variables de entorno de Intlayer dentro de los entornos de Webpack o Turbopack. Además, proporciona alias para optimizar el rendimiento y garantiza la compatibilidad con los server components.

    La función withIntlayer() es una función que devuelve una promesa. Permite preparar los diccionarios de Intlayer antes de que comience la compilación. Si quieres usarla con otros plugins, puedes usar await. Ejemplo:

    const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

    Si quieres usarlo de forma sincrónica, puedes usar la función withIntlayerSync(). Ejemplo:

    const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;

    Intlayer detecta automáticamente si tu proyecto está usando webpack o Turbopack basándose en las banderas de línea de comandos --webpack, --turbo, o --turbopack, así como en tu versión de Next.js actual.

    Desde next>=16, si estás usando Rspack, debes forzar explícitamente a Intlayer a usar la configuración de webpack deshabilitando Turbopack:

    withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));

    Paso 4: Definir rutas locales dinámicas

    Elimina todo de RootLayout y reemplázalo con el siguiente código:

    src/app/layout.tsx
    import type { Metadata } from "next";import type { ReactNode } from "react";import "./globals.css";import { IntlayerClientProvider, LocalPromiseParams } from "next-intlayer";import { getHTMLTextDir, getIntlayer } from "intlayer";import { getLocale } from "next-intlayer/server";export { generateStaticParams } from "next-intlayer";export const generateMetadata = async ({  params,}: LocalPromiseParams): Promise<Metadata> => {  const { locale } = await params;  const { title, description, keywords } = getIntlayer("metadata", locale);  return {    title,    description,    keywords,  };};const RootLayout = async ({  children,}: Readonly<{  children: ReactNode;}>) => {  const locale = await getLocale();  return (    <html lang={locale} dir={getHTMLTextDir(locale)}>      <IntlayerClientProvider defaultLocale={locale}>        <body>{children}</body>      </IntlayerClientProvider>    </html>  );};export default RootLayout;

    Paso 5: Declarar su contenido

    Cree y gestione sus declaraciones de contenido para almacenar traducciones:

    src/app/metadata.content.ts
    import { t, type Dictionary } from "intlayer";import { Metadata } from "next";const metadataContent = {  key: "metadata",  content: {    title: t({      es: "El Título de mi Proyecto",      en: "My Project Title",      fr: "Le Titre de mon Projet",    }),    description: t({      es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",      en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",      fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",      es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",    }),    keywords: t({      en: ["innovation", "productivity", "workflow", "SaaS"],      fr: ["innovation", "productivité", "flux de travail", "SaaS"],      es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],    }),  },} as Dictionary<Metadata>;export default metadataContent;
    src/app/metadata.content.mjs
    import { t, type Dictionary } from "intlayer";/** @type {import('intlayer').Dictionary<import('next').Metadata>} */const metadataContent = {  key: "metadata",  content: {    title: t({      es: "El Título de mi Proyecto",      en: "My Project Title",      fr: "Le Titre de mon Projet",    }),    description: t({      es: "Descubra nuestra plataforma innovadora diseñada para simplificar su flujo de trabajo y aumentar su productividad.",      en: "Discover our innovative platform designed to streamline your workflow and boost productivity.",      fr: "Découvrez notre plateforme innovante conçue pour simplifier votre flux de travail et booster votre productivité.",    }),    keywords: t({      es: ["innovación", "productividad", "flujo de trabajo", "SaaS"],      en: ["innovation", "productivity", "workflow", "SaaS"],      fr: ["innovation", "productivité", "flux de travail", "SaaS"],    }),  },};export default metadataContent;
    src/app/page.content.ts
    import { t, type Dictionary } from "intlayer";const pageContent = {  key: "page",  content: {    getStarted: {      main: t({        es: "Comience por editar",        en: "Get started by editing",        fr: "Commencez par éditer",      }),      pageLink: "src/app/page.tsx",    },  },} satisfies Dictionary;export default pageContent;
    Tus declaraciones de contenido pueden definirse en cualquier lugar de tu aplicación siempre que se incluyan en el directorio contentDir (por defecto, ./src). Y coincidan con la extensión de archivo de declaración de contenido (por defecto, .content.{json,ts,tsx,js,jsx,mjs,mjx,cjs,cjx}).
    Para más detalles, consulta la documentación de declaraciones de contenido.

    Paso 6: Utiliza el contenido en tu código

    Accede a los diccionarios de contenido desde cualquier parte de tu aplicación:

    src/app/page.tsx
    import type { FC } from "react";import { ClientComponentExample } from "@components/clientComponentExample/ClientComponentExample";import { ServerComponentExample } from "@components/serverComponentExample/ServerComponentExample";import {  IntlayerServerProvider,  useIntlayer,  getLocale,} from "next-intlayer/server";import { NextPage } from "next";import { headers, cookies } from "next/headers";const PageContent: FC = () => {  const content = useIntlayer("page");  return (    <>      <p>{content.getStarted.main}</p>      <code>{content.getStarted.pageLink}</code>    </>  );};const Page: NextPage = async () => {  // Espera headers y cookies en Next.js 15+  const headerList = await headers();  const cookieList = await cookies();  const locale = await getLocale({    // Primero verifica la cookie de intlayer (por defecto: 'INTLAYER_LOCALE')    getCookie: (name) => cookieList.get(name)?.value,    // Luego verifica el header de intlayer (por defecto: 'x-intlayer-locale')    // Y finalmente verifica el header accept-language ('accept-language')    getHeader: (name) => headerList.get(name),  });  return (    <IntlayerServerProvider locale={locale}>      <PageContent />      <ServerComponentExample />      <ClientComponentExample />    </IntlayerServerProvider>  );};export default Page;
    • IntlayerClientProvider se utiliza para proporcionar el locale a los componentes del lado del cliente. Puede colocarse en cualquier componente padre, incluido el layout. Sin embargo, se recomienda colocarlo en un layout porque Next.js comparte el código del layout entre páginas, lo que lo hace más eficiente. Al usar IntlayerClientProvider en el layout, evitas reinicializarlo en cada página, mejorando el rendimiento y manteniendo un contexto de localización coherente en toda la aplicación.
    • IntlayerServerProvider se utiliza para proporcionar el locale a los hijos en el servidor. No puede establecerse en el layout.
    El layout y la página no pueden compartir un contexto del servidor común porque el sistema de contexto del servidor se basa en un almacenamiento de datos por solicitud (a través del mecanismo de cache de React), lo que hace que cada "context" se vuelva a crear para diferentes segmentos de la aplicación. Colocar el provider en un layout compartido rompería este aislamiento, impidiendo la propagación correcta de los valores del contexto del servidor a tus server components.
    src/components/clientComponentExample/ClientComponentExample.tsx
    "use client";import type { FC } from "react";import { useIntlayer } from "next-intlayer";export const ClientComponentExample: FC = () => {  const content = useIntlayer("client-component-example"); // Crear declaración de contenido relacionada  return (    <div>      <h2>{content.title}</h2>      <p>{content.content}</p>    </div>  );};
    src/components/serverComponentExample/ServerComponentExample.tsx
    import type { FC } from "react";import { useIntlayer } from "next-intlayer/server";export const ServerComponentExample: FC = () => {  const content = useIntlayer("server-component-example"); // Crear la declaración de contenido relacionada  return (    <div>      <h2>{content.title}</h2>      <p>{content.content}</p>    </div>  );};

    Si desea usar su contenido en un atributo de tipo string, como alt, title, href, aria-label, etc., debe invocar el valor de la función, por ejemplo:

    <img src={content.image.src.value} alt={content.image.value} />

    Para saber más sobre el hook useIntlayer, consulte la documentación.

    (Opcional) Paso 7: Configurar el proxy para la detección del locale

    Configura el proxy para detectar el locale preferido del usuario:

    src/proxy.ts
    export { intlayerProxy as proxy } from "next-intlayer/proxy";export const config = {  matcher:    "/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",};
    El intlayerProxy se utiliza para detectar el locale preferido del usuario y redirigirle a la URL correspondiente según se especifica en la configuración. Además, permite guardar el locale preferido del usuario en una cookie.
    Si necesitas encadenar varios proxies (por ejemplo, intlayerProxy con autenticación o proxies personalizados), Intlayer ahora proporciona un helper llamado multipleProxies.
    import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);

    (Opcional) Paso 8: Cambiar el idioma de tu contenido

    Para cambiar el idioma de tu contenido en Next.js, la forma recomendada es usar el componente Link para redirigir a los usuarios a la página localizada correspondiente. El componente Link habilita la precarga (prefetch) de la página, lo que ayuda a evitar una recarga completa de la página.

    src/components/localeSwitcher/LocaleSwitcher.tsx
    "use client";import type { FC } from "react";import { Locales, getHTMLTextDir, getLocaleName } from "intlayer";import { useLocale } from "next-intlayer";export const LocaleSwitcher: FC = () => {  const { locale, availableLocales, setLocale } = useLocale({    onChange: () => window.location.reload(),  });  return (    <div>      <button popoverTarget="localePopover">{getLocaleName(locale)}</button>      <div id="localePopover" popover="auto">        {availableLocales.map((localeItem) => (          <button            key={localeItem}            aria-current={locale === localeItem ? "page" : undefined}            onClick={() => setLocale(localeItem)}          >            <span>              {/* Locale - p. ej. FR */}              {localeItem}            </span>            <span>              {/* Idioma en su propio locale - p. ej. Français */}              {getLocaleName(localeItem, locale)}            </span>            <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>              {/* Idioma en el locale actual - p. ej. Francés con el locale actual establecido en Locales.SPANISH */}              {getLocaleName(localeItem)}            </span>            <span dir="ltr" lang={Locales.ENGLISH}>              {/* Idioma en inglés - p. ej. French */}              {getLocaleName(localeItem, Locales.ENGLISH)}            </span>          </button>        ))}      </div>    </div>  );};
    Una alternativa es usar la función setLocale proporcionada por el hook useLocale. Esta función no permitirá el prefetch de la página. Consulta la documentación del hook useLocale para más detalles.

    Referencias de la documentación:

    (Opcional) Paso 9: Obtener la locale actual en Server Actions

    Si necesitas la locale activa dentro de una Server Action (p. ej., para localizar correos electrónicos o ejecutar lógica dependiente de la locale), llama a getLocale desde next-intlayer/server:

    src/app/actions/getLocale.ts
    "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Haz algo con la locale};

    La función getLocale sigue una estrategia en cascada para determinar la locale del usuario:

    1. Primero, comprueba las cabeceras de la petición en busca de un valor de locale que pueda haber sido establecido por el proxy
    2. Si no se encuentra locale en las cabeceras, busca un locale almacenado en cookies
    3. Si no se encuentra cookie, intenta detectar el idioma preferido del usuario a partir de la configuración del navegador
    4. Como último recurso, recurre al locale predeterminado configurado en la aplicación

    Esto asegura que se seleccione el locale más apropiado según el contexto disponible.

    (Opcional) Paso 10: Optimiza el tamaño del bundle

    Al usar next-intlayer, los diccionarios se incluyen en el bundle para cada página por defecto. Para optimizar el tamaño del bundle, Intlayer proporciona un plugin SWC opcional que reemplaza inteligentemente las llamadas a useIntlayer usando macros. Esto asegura que los diccionarios solo se incluyan en los bundles de las páginas que realmente los utilizan.

    Para habilitar esta optimización, instala el paquete @intlayer/swc. Una vez instalado, next-intlayer detectará y usará automáticamente el plugin:

    bash
    npm install @intlayer/swc --save-devnpx intlayer init
    Nota: Esta optimización solo está disponible para Next.js 13 y versiones superiores.
    Nota: Este paquete no se instala por defecto porque los plugins de SWC siguen siendo experimentales en Next.js. Esto podría cambiar en el futuro.
    Nota: Si configuras la opción como importMode: 'dynamic' o importMode: 'live', dependerá de Suspense, por lo que tendrás que envolver tus llamadas a useIntlayer en un límite de Suspense. Eso significa que no podrás usar useIntlayer directamente en el nivel superior de tu componente Page / Layout.

    Supervisar cambios en los diccionarios con Turbopack

    Cuando uses Turbopack como servidor de desarrollo con el comando next dev, los cambios en los diccionarios no se detectarán automáticamente por defecto.

    Esta limitación se debe a que Turbopack no puede ejecutar plugins de webpack en paralelo para supervisar los cambios en tus archivos de contenido. Para evitar esto, deberás usar el comando intlayer watch para ejecutar simultáneamente tanto el servidor de desarrollo como el observador de compilación de Intlayer.

    package.json
    {  // ... Tus configuraciones existentes de package.json  "scripts": {    // ... Tus configuraciones existentes de scripts    "dev": "intlayer watch --with 'next dev'",  },}
    Si estás usando next-intlayer@<=6.x.x, debes mantener la opción --turbopack para que la aplicación Next.js 16 funcione correctamente con Turbopack. Recomendamos usar next-intlayer@>=7.x.x para evitar esta limitación.

    Configurar TypeScript

    Intlayer usa module augmentation para aprovechar TypeScript y fortalecer tu codebase.

    Autocompletado

    Error de traducción

    Asegúrate de que tu configuración de TypeScript incluya los tipos autogenerados.

    tsconfig.json
    {  // ... Tus configuraciones existentes de TypeScript  "include": [    // ... Tus configuraciones existentes de TypeScript    ".intlayer/**/*.ts", // Incluir los tipos generados automáticamente  ],}

    Configuración de Git

    Se recomienda ignorar los archivos generados por Intlayer. Esto te permite evitar comprometerlos en tu repositorio Git.

    Para ello, puedes añadir las siguientes instrucciones a tu archivo .gitignore:

    .gitignore
    # Ignorar los archivos generados por Intlayer.intlayer

    Extensión de VS Code

    Para mejorar tu experiencia de desarrollo con Intlayer, puedes instalar la Extensión oficial de Intlayer para VS Code.

    Instalar desde el VS Code Marketplace

    Esta extensión proporciona:

    • Autocompletado para claves de traducción.
    • Detección de errores en tiempo real para traducciones faltantes.
    • Previsualizaciones en línea del contenido traducido.
    • Acciones rápidas para crear y actualizar traducciones fácilmente.

    Para más detalles sobre cómo usar la extensión, consulta la documentación de la extensión de Intlayer para VS Code.

    Ir más lejos

    Para ir más lejos, puedes implementar el editor visual o externalizar tu contenido usando el CMS.

    Recibe notificaciones sobre los próximos lanzamientos de Intlayer