InicioEntorno de pruebasExhibiciónAppDocBlog
    • Englishinglés
      EN
    • русскийruso
      RU
    • 日本語japonés
      JA
    • françaisfrancés
      FR
    • 한국어coreano
      KO
    • 中文chino
      ZH
    • españolespañol
      ES
    • Deutschalemán
      DE
    • العربيةárabe
      AR
    • italianoitaliano
      IT
    • British Englishinglés británico
      EN-GB
    • portuguêsportugués
      PT
    • हिन्दीhindi
      HI
    • Türkçeturco
      TR
    • polskipolaco
      PL
    • Indonesiaindonesio
      ID
    • Tiếng Việtvietnamita
      VI
    • українськаucraniano
      UK
    /
    Filtrar documentación por framework
    Alt+←
    ¿Por qué Intlayer?
    Empezar
    Concepto
    • Cómo funciona Intlayer
    • Configuración
    • TestFillBuildWatchExtractLoginPushPullConfigurationListVersionEditorLiveDebugDoc ReviewDoc TranslateSDK
    • Editor visual
    • CMS
    • Integración CI/CD
    • TraducciónPluralEnumeraciónCondiciónGéneroInserciónArchivoAnidaciónMarkdownHTMLObtención de función
    • Archivo por locale
    • Compilador
    • Autocompletado
    • Pruebas
    • Optimización de bundle
    Entornos
    • Next.js 14 y App Router
      Next.js 15
      Next.js sin locale URL
      Next.js y Page Router
      Compiler
    • Tanstack Start Solid
    • Astro y React
      Astro y Svelte
      Astro y Vue
      Astro y Solid
      Astro y Preact
      Astro y Lit
      Astro y Vanilla JS
    • React Router v7
      React Router v7 (fs-routes)
      Compiler
    • Nuxt y Vue
    • Vite y Solid
    • SvelteKit
    • Vite y Preact
    • Vite y Vanilla JS
    • Vite y Lit
    • Angular 19 (Webpack)
      Analog
    • React CRA
    • React Native y Expo
    • Express.js
      NestJS
      Fastify
      Hono
      Adonis
    • Lynx y React
    Plugins
    • JSON
    • gettext (.po)
    Extensión VS Code
    Agente
    • Servidor MCP
    • Habilidades del agente
    Versiones
    • v8
    • v7
    • v6
    Benchmark
    • Next.js
    • TanStack
    • Vue
    • Solid
    • Svelte
    Blog
    Preguntar una pregunta
    1. Documentation
    2. Entornos
    3. Next.js
    Creación:2024-12-06Última actualización:2026-05-06
    Ver la plantilla de aplicación en GitHub

    Esta página tiene una plantilla de aplicación disponible.

    Ver la aplicación de demostración

    Esta página enlaza a una demo en vivo de la plantilla.

    Ver el video tutorial

    Esta página tiene un video tutorial disponible.

    Referencia esta doc a tu asistente AI favorito
    ChatGPT
    Claude
    DeepSeek
    Google AI mode
    Gemini
    Perplexity
    Mistral
    Grok

    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

    1. "Actualizar el uso de la API useIntlayer de Solid para el acceso directo a las propiedades"
      v8.9.04/5/2026
    2. "Agregar comando init"
      v7.5.930/12/2025
    3. "Se agregó la mención de `x-default` en el objeto `alternates`"
      v7.0.61/11/2025
    4. "Historial inicial"
      v7.0.029/6/2025

    El contenido de esta página ha sido traducido con una IA.

    Ver la última versión del contenido original en inglés
    Editar esta documentación

    Si tienes una idea para mejorar esta documentación, no dudes en contribuir enviando una pull request en GitHub.

    Enlace de GitHub a la documentación
    Copiar

    Copiar el Markdown del documento a la portapapeles

    Traduce tu sitio web Next.js 16 usando Intlayer | Internacionalización (i18n)

    www.youtube.com
    ide.intlayer.org
    intlayer-next-16-template.vercel.app

    Consulta la Plantilla de Aplicación en GitHub.

    Tabla de Contenidos

    ¿Qué es Intlayer?

    Intlayer es una biblioteca innovadora y de código abierto para la internacionalización (i18n) diseñada para simplificar el soporte multilingüe en aplicaciones web modernas. Intlayer se integra perfectamente con el último framework Next.js 16, incluyendo su potente App Router. Está optimizado para trabajar con Componentes del Servidor para un renderizado eficiente y es totalmente compatible con Turbopack.

    Con Intlayer, puedes:

    • Gestionar traducciones fácilmente 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 servidor.
    • Garantizar soporte para TypeScript con tipos autogenerados, mejorando la autocompletación y la detección de errores.
    • Benefíciate de funciones avanzadas, como la detección y el cambio dinámico de locales.

    Intlayer es compatible con Next.js 12, 13, 14 y 16. Si usas Next.js Page Router, puedes consultar esta guía. El enrutamiento regional es útil para el SEO, el tamaño del paquete (bundle) y el rendimiento. Si no lo necesitas, puedes consultar esta guía. Para Next.js 12, 13, 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
    Copiar código

    Copiar el código al portapapeles

    npm install intlayer next-intlayernpx intlayer init
    • intlayer

      El paquete principal 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 configuración regional preferida del usuario, gestionar cookies y manejar la redirección de URL.

    Paso 2: Configura tu proyecto

    Here is the final structure that we will make:

    bash
    Copiar código

    Copiar el código al portapapeles

    .├── src│   ├── app│   │   ├── [locale]│   │   │   ├── layout.tsx            # Locale layout for the Intlayer provider│   │   │   ├── page.content.ts│   │   │   └── page.tsx│   │   └── layout.tsx                # Root layout for style and global providers│   ├── components│   │   ├── client-component-example.content.ts│   │   ├── ClientComponentExample.tsx│   │   ├── LocaleSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   ├── server-component-example.content.ts│   │   └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
    If you don't want locale routing, intlayer can be used as a simple provider / hook. See this guide for more details.

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

    intlayer.config.ts
    Copiar código

    Copiar el código al portapapeles

    import { Locales, type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      internationalization: {
        locales: [
          Locales.ENGLISH,
          Locales.FRENCH,
          Locales.SPANISH,
          // Tus otros locales
        ],
        defaultLocale: Locales.ENGLISH,
      },
    };
    
    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 registros 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: Integra Intlayer en tu configuración de Next.js

    Configura tu entorno Next.js para usar Intlayer:

    next.config.ts
    Copiar código

    Copiar el código al portapapeles

    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 withIntlayer() de Next.js se utiliza para integrar Intlayer con Next.js. Garantiza la construcción de archivos de declaración de contenido y los supervisa en modo de desarrollo. Define variables de entorno de Intlayer dentro de los entornos de Webpack o Turbopack. Además, proporciona alias para optimizar el rendimiento y asegura la compatibilidad con componentes del servidor.

    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 deseas usarla con otros plugins, puedes usar await. Ejemplo:

    tsx
    Copiar código

    Copiar el código al portapapeles

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

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

    tsx
    Copiar código

    Copiar el código al portapapeles

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

    Intlayer detecta automáticamente si su proyecto utiliza webpack o Turbopack según los flags de línea de comandos --webpack, --turbo o --turbopack, así como su versión actual de Next.js.

    Desde next>=16, si utiliza Rspack, debe forzar explícitamente a Intlayer a usar la configuración de webpack deshabilitando Turbopack:

    ts
    Copiar código

    Copiar el código al portapapeles

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

    Paso 4: Definir Rutas Dinámicas de Localización

    Elimina todo lo que hay en RootLayout y reemplázalo con el siguiente código:

    src/app/layout.tsx
    Copiar código

    Copiar el código al portapapeles

    import type { PropsWithChildren, FC } from "react";
    import "./globals.css";
    
    const RootLayout: FC<PropsWithChildren> = ({ children }) => (
      // Aún puedes envolver los children con otros proveedores, como `next-themes`, `react-query`, `framer-motion`, etc.
      <>{children}</>
    );
    
    export default RootLayout;
    Mantener el componente RootLayout vacío permite establecer los atributos lang y dir en la etiqueta <html>.

    Para implementar el enrutamiento dinámico, proporciona la ruta para la localización añadiendo un nuevo layout en tu directorio [locale]:

    src/app/[locale]/layout.tsx
    Copiar código

    Copiar el código al portapapeles

    import { type NextLayoutIntlayer, IntlayerClientProvider } from "next-intlayer";
    import { Inter } from "next/font/google";
    import { getHTMLTextDir } from "intlayer";
    
    const inter = Inter({ subsets: ["latin"] });
    
    const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
      const { locale } = await params;
      return (
        <html lang={locale} dir={getHTMLTextDir(locale)}>
          <body className={inter.className}>
            <IntlayerClientProvider locale={locale}>
              {children}
            </IntlayerClientProvider>
          </body>
        </html>
      );
    };
    
    export default LocaleLayout;
    El segmento de ruta [locale] se utiliza para definir la configuración regional. Ejemplo: /en-US/about se referirá a en-US y /fr/about a fr.
    En esta etapa, encontrará el error: Error: Missing <html> and <body> tags in the root layout.. Esto es esperado porque el archivo /app/page.tsx ya no se utiliza y puede ser eliminado. En su lugar, el segmento de ruta [locale] activará la página /app/[locale]/page.tsx. En consecuencia, las páginas serán accesibles a través de rutas como /en, /fr, /es en su navegador. Para establecer la configuración regional predeterminada como la página raíz, consulte la configuración del proxy en el paso 7.

    Luego, implemente la función generateStaticParams en el Layout de su aplicación.

    src/app/[locale]/layout.tsx
    Copiar código

    Copiar el código al portapapeles

    export { generateStaticParams } from "next-intlayer"; // Línea para insertar
    
    const LocaleLayout: NextLayoutIntlayer = async ({ children, params }) => {
      /*... Resto del código*/
    };
    
    export default LocaleLayout;

    generateStaticParams asegura que tu aplicación preconstruya las páginas necesarias para todos los locales, reduciendo el cálculo en tiempo de ejecución y mejorando la experiencia del usuario. Para más detalles, consulta la documentación de Next.js sobre generateStaticParams.

    Intlayer funciona con export const dynamic = 'force-static'; para asegurar que las páginas se preconstruyan para todos los locales.

    Paso 5: Declara Tu Contenido

    Crea y gestiona tus declaraciones de contenido para almacenar traducciones:

    src/app/[locale]/page.content.ts
    Copiar código

    Copiar el código al portapapeles

    import { t, type Dictionary } from "intlayer";
    
    const pageContent = {
      key: "page",
      content: {
        getStarted: {
          main: t({
            en: "Get started by editing",
            fr: "Commencez par éditer",
            es: "Comience por editar",
          }),
          pageLink: "src/app/page.tsx",
        },
      },
    } satisfies Dictionary;
    
    export default pageContent;
    Tus declaraciones de contenido pueden definirse en cualquier parte de tu aplicación siempre que estén incluidas 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,cjs}).
    Para más detalles, consulta la documentación de declaración de contenido.

    Paso 6: Utiliza el contenido en tu código

    Accede a tus diccionarios de contenido en toda tu aplicación:

    src/app/[locale]/page.tsx
    Copiar código

    Copiar el código al portapapeles

    import type { FC } from "react";
    import { ClientComponentExample } from "@components/ClientComponentExample";
    import { ServerComponentExample } from "@components/ServerComponentExample";
    import { type NextPageIntlayer } from "next-intlayer";
    import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
    
    const PageContent: FC = () => {
      const content = useIntlayer("page");
    
      return (
        <>
          <p>{content.getStarted.main}</p>
          <code>{content.getStarted.pageLink}</code>
        </>
      );
    };
    
    const Page: NextPageIntlayer = async ({ params }) => {
      const { locale } = await params;
    
      return (
        <IntlayerServerProvider locale={locale}>
          <PageContent />
          <ServerComponentExample />
    
          <ClientComponentExample />
        </IntlayerServerProvider>
      );
    };
    
    export default Page;
    • IntlayerClientProvider se utiliza para proporcionar la configuración regional 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 para cada página, mejorando el rendimiento y manteniendo un contexto de localización consistente en toda tu aplicación.
    • IntlayerServerProvider se utiliza para proporcionar la configuración regional a los componentes hijos del servidor. No puede establecerse en el layout.

      El layout y la página no pueden compartir un contexto común del servidor porque el sistema de contexto del servidor se basa en un almacén de datos por solicitud (a través del mecanismo React's cache), lo que provoca que cada "contexto" se recree para diferentes segmentos de la aplicación. Colocar el proveedor en un layout compartido rompería este aislamiento, impidiendo la correcta propagación de los valores del contexto del servidor a tus componentes del servidor.
      El layout y la página no pueden compartir un contexto de servidor común porque el sistema de contexto de servidor se basa en un almacén de datos por solicitud (a través del mecanismo de caché de React), lo que provoca que cada "contexto" se vuelva a crear para diferentes segmentos de la aplicación. Colocar el proveedor en un layout compartido rompería este aislamiento, impidiendo la correcta propagación de los valores del contexto del servidor a tus componentes del servidor.
    src/components/ClientComponentExample.tsx
    Copiar código

    Copiar el código al portapapeles

    "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.tsx
    Copiar código

    Copiar el código al portapapeles

    import type { FC } from "react";
    import { useIntlayer } from "next-intlayer/server";
    
    export const ServerComponentExample: FC = () => {
      const content = useIntlayer("server-component-example"); // Crear declaración de contenido relacionado
    
      return (
        <div>
          <h2>{content.title}</h2>
          <p>{content.content}</p>
        </div>
      );
    };
    Si quieres usar tu contenido en un atributo de tipo string, como alt, title, href, aria-label, etc., debes llamar al valor de la función, así:
    html
    Copiar código

    Copiar el código al portapapeles

    <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
    Para aprender más sobre el hook useIntlayer, consulta la documentación.
    Si su aplicación ya existe, puede utilizar el Compilador Intlayer, así como el comando de extracción, para transformar miles de componentes en un segundo.

    (Opcional) Paso 7: Configurar Proxy para la Detección de Idioma

    Configura un proxy para detectar el idioma preferido del usuario:

    src/proxy.ts
    Copiar código

    Copiar el código al portapapeles

    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 la configuración regional preferida del usuario y redirigirlo a la URL apropiada según lo especificado en la configuración. Además, permite guardar la configuración regional preferida del usuario en una cookie.
    Si necesitas encadenar varios proxies juntos (por ejemplo, intlayerProxy con autenticación o proxies personalizados), Intlayer ahora proporciona una ayuda llamada multipleProxies.
    ts
    Copiar código

    Copiar el código al portapapeles

    import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);

    (Opcional) Paso 8: Internacionalización de tus metadatos

    En caso de que desees internacionalizar tus metadatos, como el título de tu página, puedes usar la función generateMetadata proporcionada por Next.js. Dentro, puedes obtener el contenido de la función getIntlayer para traducir tus metadatos.

    src/app/[locale]/metadata.content.ts
    Copiar código

    Copiar el código al portapapeles

    import { type Dictionary, t } from "intlayer";
    import { Metadata } from "next";
    
    const metadataContent = {
      key: "page-metadata",
      content: {
        title: t({
          en: "Create Next App",
          fr: "Créer une application Next.js",
          es: "Crear una aplicación Next.js",
        }),
        description: t({
          en: "Generated by create next app",
          fr: "Généré par create next app",
          es: "Generado por create next app",
        }),
      },
    } satisfies Dictionary<Metadata>;
    
    export default metadataContent;
    src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx
    Copiar código

    Copiar el código al portapapeles

    import { getIntlayer, getMultilingualUrls } from "intlayer";
    import type { Metadata } from "next";
    import type { LocalPromiseParams } from "next-intlayer";
    
    export const generateMetadata = async ({
      params,
    }: LocalPromiseParams): Promise<Metadata> => {
      const { locale } = await params;
    
      const metadata = getIntlayer("page-metadata", locale);
    
      /**
       * Genera un objeto que contiene todas las URLs para cada idioma.
       *
       * Ejemplo:
       * ```ts
       *  getMultilingualUrls('/about');
       *
       *  // Devuelve
       *  // {
       *  //   en: '/about',
       *  //   fr: '/fr/about',
       *  //   es: '/es/about',
       *  // }
       * ```
       */
      const multilingualUrls = getMultilingualUrls("/");
      const localizedUrl =
        multilingualUrls[locale as keyof typeof multilingualUrls];
    
      return {
        ...metadata,
        alternates: {
          canonical: localizedUrl,
          languages: { ...multilingualUrls, "x-default": "/" },
        },
        openGraph: {
          url: localizedUrl,
        },
      };
    };
    
    // ... Resto del código
    Tenga en cuenta que la función getIntlayer importada desde next-intlayer devuelve su contenido envuelto en un IntlayerNode, lo que permite la integración con el editor visual. En cambio, la función getIntlayer importada desde intlayer devuelve su contenido directamente sin propiedades adicionales.

    Alternativamente, puedes usar la función getTranslation para declarar tus metadatos. Sin embargo, se recomienda usar archivos de declaración de contenido para automatizar la traducción de tus metadatos y externalizar el contenido en algún momento.

    src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx
    Copiar código

    Copiar el código al portapapeles

    import {
      type IConfigLocales,
      getTranslation,
      getMultilingualUrls,
    } from "intlayer";
    import type { Metadata } from "next";
    import type { LocalPromiseParams } from "next-intlayer";
    
    export const generateMetadata = async ({
      params,
    }: LocalPromiseParams): Promise<Metadata> => {
      const { locale } = await params;
      const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
    
      return {
        title: t<string>({
          en: "My title",
    Alternativamente, puedes usar la función `getTranslation` para declarar tus metadatos. Sin embargo, se recomienda usar archivos de declaración de contenido para automatizar la traducción de tus metadatos y externalizar el contenido en algún momento.
    
    ```typescript fileName="src/app/[locale]/layout.tsx or src/app/[locale]/page.tsx" codeFormat="typescript"
    import {
      type IConfigLocales,
      getTranslation,
      getMultilingualUrls,
    } from "intlayer";
    import type { Metadata } from "next";
    import type { LocalPromiseParams } from "next-intlayer";
    
    export const generateMetadata = async ({
      params,
    }: LocalPromiseParams): Promise<Metadata> => {
      const { locale } = await params;
      const t = <T>(content: IConfigLocales<T>) => getTranslation(content, locale);
    
      return {
        title: t<string>({
          en: "My title",
          fr: "Mon titre",
          es: "Mi título",
        }),
        description: t({
          en: "My description",
          fr: "Ma description",
          es: "Mi descripción",
        }),
      };
    };
    
    // ... Resto del código
    Aprende más sobre la optimización de metadatos en la documentación oficial de Next.js.
    plaintext
    Copiar código

    Copiar el código al portapapeles

    ```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"const { getTranslation, getMultilingualUrls } = require("intlayer");const generateMetadata = async ({ params }) => {  const { locale } = await params;  const t = (content) => getTranslation(content, locale);  return {    title: t({      en: "My title",      fr: "Mon titre",      es: "Mi título",    }),    description: t({      en: "My description",      fr: "Ma description",      es: "Mi descripción",    }),  };};module.exports = { generateMetadata };// ... Resto del código
    Aprende más sobre la optimización de metadatos en la documentación oficial de Next.js.

    (Opcional) Paso 9: Internacionalización de tu sitemap.xml y robots.txt

    Para internacionalizar tu sitemap.xml y robots.txt, puedes usar la función getMultilingualUrls proporcionada por Intlayer. Esta función te permite generar URLs multilingües para tu sitemap.

    src/app/sitemap.ts
    Copiar código

    Copiar el código al portapapeles

    import { getMultilingualUrls } from "intlayer";
    import type { MetadataRoute } from "next";
    
    const sitemap = (): MetadataRoute.Sitemap => [
      {
        url: "https://example.com",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com"),
            "x-default": "https://example.com",
          },
        },
      },
      {
        url: "https://example.com/login",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com/login"),
            "x-default": "https://example.com/login",
          },
        },
      },
      {
        url: "https://example.com/register",
        alternates: {
          languages: {
            ...getMultilingualUrls("https://example.com/register"),
            "x-default": "https://example.com/register",
          },
        },
      },
    ];
    
    export default sitemap;
    src/app/robots.ts
    Copiar código

    Copiar el código al portapapeles

    import type { MetadataRoute } from "next";
    import { getMultilingualUrls } from "intlayer";
    
    const getAllMultilingualUrls = (urls: string[]) =>
      urls.flatMap((url) => Object.values(getMultilingualUrls(url)) as string[]);
    
    // Configuración de reglas para robots.txt
    const robots = (): MetadataRoute.Robots => ({
      rules: {
        userAgent: "*", // Aplica a todos los agentes de usuario
        allow: ["/"], // Permite acceso a la raíz
        disallow: getAllMultilingualUrls(["/login", "/register"]), // Bloquea URLs multilingües de login y registro
      },
      host: "https://example.com",
      sitemap: `https://example.com/sitemap.xml`,
    });
    
    export default robots;
    Aprende más sobre la optimización del sitemap en la documentación oficial de Next.js. Aprende más sobre la optimización del archivo robots.txt en la documentación oficial de Next.js.

    (Opcional) Paso 10: Cambia 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 permite la precarga de la página, lo que ayuda a evitar una recarga completa de la página.

    src/components/LocaleSwitcher.tsx
    Copiar código

    Copiar el código al portapapeles

    "use client";
    
    import type { FC } from "react";
    import {
      Locales,
      getHTMLTextDir,
      getLocaleName,
      getLocalizedUrl,
    } from "intlayer";
    import { useLocale } from "next-intlayer";
    import Link from "next/link";
    
    export const LocaleSwitcher: FC = () => {
      const { locale, pathWithoutLocale, availableLocales, setLocale } =
        useLocale();
    
      return (
        <div>
          <button popoverTarget="localePopover">{getLocaleName(locale)}</button>
          <div id="localePopover" popover="auto">
            {availableLocales.map((localeItem) => (
              <Link
                href={getLocalizedUrl(pathWithoutLocale, localeItem)}
                key={localeItem}
                aria-current={locale === localeItem ? "page" : undefined}
                onClick={() => setLocale(localeItem)}
                replace // Esto asegurará que el botón "volver" del navegador redirija a la página anterior
              >
                <span>
                  {/* Local - p. ej., FR */}
                  {localeItem}
                </span>
                <span>
                  {/* Idioma en su propia localización - p. ej., Français */}
                  {getLocaleName(localeItem, locale)}
                </span>
                <span dir={getHTMLTextDir(localeItem)} lang={localeItem}>
                  {/* Idioma en la localización actual - p. ej., Francés con la localización actual configurada en Locales.SPANISH */}
                  {getLocaleName(localeItem)}
                </span>
                <span dir="ltr" lang={Locales.ENGLISH}>
                  {/* Idioma en inglés - p. ej., French */}
                  {getLocaleName(localeItem, Locales.ENGLISH)}
                </span>
              </Link>
            ))}
          </div>
        </div>
      );
    };
    Una forma alternativa es usar la función setLocale proporcionada por el hook useLocale. Esta función no permitirá la precarga de la página. Consulta la documentación del hook useLocale para más detalles.
    También puedes establecer una función en la opción onLocaleChange para activar una función personalizada cuando cambie la configuración regional.
    src/components/LocaleSwitcher.tsx
    Copiar código

    Copiar el código al portapapeles

    "use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Resto del códigoconst router = useRouter();const { setLocale } = useLocale({  onLocaleChange: (locale) => {    router.push(getLocalizedUrl(pathWithoutLocale, locale));  },});return (  <button onClick={() => setLocale(Locales.FRENCH)}>Cambiar a francés</button>);

    Referencias de la documentación:

    • useLocale hook
    • getLocaleName hook
    • getLocalizedUrl hook
    • getHTMLTextDir hook
    • hrefLang attribute
    • lang attribute
    • dir attribute`
    • aria-current attribute`

    (Opcional) Paso 11: Creación de un Componente de Enlace Localizado

    Para asegurar que la navegación de tu aplicación respete la configuración regional actual, puedes crear un componente personalizado Link. Este componente antepone automáticamente a las URLs internas el idioma actual. Por ejemplo, cuando un usuario francófono hace clic en un enlace a la página "Acerca de", es redirigido a /fr/about en lugar de /about.

    Este comportamiento es útil por varias razones:

    • SEO y experiencia del usuario: Las URLs localizadas ayudan a los motores de búsqueda a indexar correctamente las páginas específicas por idioma y proporcionan a los usuarios contenido en su idioma preferido.
    • Consistencia: Al usar un enlace localizado en toda tu aplicación, garantizas que la navegación se mantenga dentro de la configuración regional actual, evitando cambios inesperados de idioma.
    • Mantenibilidad: Centralizar la lógica de localización en un solo componente simplifica la gestión de URLs, haciendo que tu base de código sea más fácil de mantener y ampliar a medida que tu aplicación crece.

    A continuación se muestra la implementación de un componente Link localizado en TypeScript:

    src/components/Link.tsx
    Copiar código

    Copiar el código al portapapeles

    "use client";
    
    import { getLocalizedUrl } from "intlayer";
    import NextLink, { type LinkProps as NextLinkProps } from "next/link";
    import { useLocale } from "next-intlayer";
    import type { PropsWithChildren, FC } from "react";
    
    /**
     * Función utilitaria para verificar si una URL dada es externa.
     * Si la URL comienza con http:// o https://, se considera externa.
     */
    export const checkIsExternalLink = (href?: string): boolean =>
      /^https?:\/\//.test(href ?? "");
    
    /**
     * Un componente Link personalizado que adapta el atributo href según la configuración regional actual.
     * Para enlaces internos, utiliza `getLocalizedUrl` para anteponer la configuración regional a la URL (por ejemplo, /fr/about).
     * Esto asegura que la navegación se mantenga dentro del mismo contexto regional.
     */
    export const Link: FC<PropsWithChildren<NextLinkProps>> = ({
      href,
      children,
      ...props
    }) => {
      const { locale } = useLocale();
      const isExternalLink = checkIsExternalLink(href.toString());
    
      // Si el enlace es interno y se proporciona un href válido, obtiene la URL localizada.
      const hrefI18n: NextLinkProps["href"] =
        href && !isExternalLink ? getLocalizedUrl(href.toString(), locale) : href;
    
      return (
        <NextLink href={hrefI18n} {...props}>
          {children}
        </NextLink>
      );
    };

    Cómo Funciona

    • Detección de Enlaces Externos:
      La función auxiliar checkIsExternalLink determina si una URL es externa. Los enlaces externos se dejan sin cambios porque no necesitan localización.

    • Recuperar la configuración regional actual:
      El hook useLocale proporciona la configuración regional actual (por ejemplo, fr para francés).

    • Localizar la URL:
      Para enlaces internos (es decir, no externos), se utiliza getLocalizedUrl para prefijar automáticamente la URL con la configuración regional actual. Esto significa que si tu usuario está en francés, pasar /about como href se transformará en /fr/about.

    • Devolver el enlace:
      El componente devuelve un elemento <a> con la URL localizada, asegurando que la navegación sea coherente con la configuración regional.

    Al integrar este componente Link en toda su aplicación, mantiene una experiencia de usuario coherente y consciente del idioma, al mismo tiempo que se beneficia de una mejor SEO y usabilidad.

    (Opcional) Paso 12: Obtener la configuración regional actual en las Acciones del Servidor

    Si necesita la configuración regional activa dentro de una Acción del Servidor (por ejemplo, para localizar correos electrónicos o ejecutar lógica dependiente del idioma), llame a getLocale desde next-intlayer/server:

    src/app/actions/getLocale.ts
    Copiar código

    Copiar el código al portapapeles

    "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Hacer algo con la configuración regional};

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

    1. Primero, verifica en los encabezados de la solicitud si hay un valor de configuración regional que pueda haber sido establecido por el proxy
    2. Si no se encuentra una configuración regional en los encabezados, busca una configuración regional almacenada en las cookies
    3. Si no se encuentra ninguna cookie, intenta detectar el idioma preferido del usuario a partir de la configuración de su navegador
    4. Como último recurso, utiliza la configuración regional predeterminada configurada en la aplicación

    Esto asegura que se seleccione la configuración regional más apropiada según el contexto disponible.

    (Opcional) Paso 13: Optimiza el tamaño de tu paquete

    Al usar next-intlayer, los diccionarios se incluyen en el paquete para cada página por defecto. Para optimizar el tamaño del paquete, 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 paquetes de las páginas que realmente los usan.

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

    bash
    Copiar código

    Copiar el código al portapapeles

    npm install @intlayer/swc --save-dev
    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 SWC aún son experimentales en Next.js. Esto podría cambiar en el futuro.

    Nota: Si establece la opción como importMode: 'dynamic' o importMode: 'fetch' (en la configuración del diccionario), dependerá de Suspense, por lo que tendrá que envolver sus llamadas a useIntlayer en un límite de Suspense. Eso significa que no podrá usar useIntlayer directamente en el nivel superior de su componente Página / Layout.

    Supervisar cambios en los diccionarios con Turbopack

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

    Esta limitación ocurre porque Turbopack no puede ejecutar plugins de webpack en paralelo para monitorear cambios en tus archivos de contenido. Para solucionar esto, necesitarás usar el comando intlayer watch para ejecutar simultáneamente el servidor de desarrollo y el observador de compilación de Intlayer.

    package.json
    Copiar código

    Copiar el código al portapapeles

    {  // ... Tus configuraciones existentes en package.json  "scripts": {    // ... Tus configuraciones existentes de scripts    "dev": "intlayer watch --with 'next dev'",  },}
    Si estás usando next-intlayer@<=6.x.x, necesitas mantener el flag --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.

    (Opcional) Paso 14 : Extraer el contenido de tus componentes

    Si tienes una base de código existente, transformar miles de archivos puede llevar mucho tiempo.

    Para facilitar este proceso, Intlayer propone un compilador / extractor para transformar tus componentes y extraer el contenido.

    Para configurarlo, puedes agregar una sección compiler en tu archivo intlayer.config.ts :

    intlayer.config.ts
    Copiar código

    Copiar el código al portapapeles

    import { type IntlayerConfig } from "intlayer";
    
    const config: IntlayerConfig = {
      // ... Resto de tu configuración
      compiler: {
        /**
         * Indica si el compilador debe estar habilitado.
         */
        enabled: true,
    
        /**
         * Define la ruta de los archivos de salida
         */
        output: ({ fileName, extension }) => `./${fileName}${extension}`,
    
        /**
         * Indica si los componentes deben guardarse después de ser transformados. De esa manera, el compilador se puede ejecutar solo una vez para transformar la aplicación y luego se puede eliminar.
         */
        saveComponents: false,
    
        /**
         * Prefijo de clave de diccionario
         */
        dictionaryKeyPrefix: "",
      },
    };
    
    export default config;

    Ejecuta el extractor para transformar tus componentes y extraer el contenido

    bash
    Copiar código

    Copiar el código al portapapeles

    npx intlayer extract
    bash
    Copiar código

    Copiar el código al portapapeles

    npm install @intlayer/babel --save-dev
    babel.config.js
    Copiar código

    Copiar el código al portapapeles

    const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // Extraer contenido de los componentes en diccionarios   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
    bash
    Copiar código

    Copiar el código al portapapeles

    npm run build # O npm run dev

    Configurar TypeScript

    Intlayer usa la ampliación de módulos para aprovechar las ventajas de TypeScript y fortalecer tu base de código.

    Autocompletado

    Error de traducción

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

    tsconfig.json
    Copiar código

    Copiar el código al portapapeles

    {  // ... Tus configuraciones existentes de TypeScript  "include": [    // ... Tus configuraciones existentes de TypeScript    ".intlayer/**/*.ts", // Include the auto-generated types  ],}

    Configuración de Git

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

    Para hacerlo, puedes agregar las siguientes instrucciones a tu archivo .gitignore:

    .gitignore
    Copiar código

    Copiar el código al portapapeles

    # Ignorar los archivos generados por Intlayer.intlayer

    Extensión para VS Code

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

    Instalar desde el Marketplace de VS Code

    Esta extensión proporciona:

    • Autocompletado para las claves de traducción.
    • Detección de errores en tiempo real para traducciones faltantes.
    • Vistas previas 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 Intlayer para VS Code.

    Ir más allá

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

    Optimización de bundle
    Next.js 14 y App Router
    Alt+→

    En esta página

      Las conversaciones son anónimas y se revisan regularmente para abordar problemas comunes. No dudes en compartir ideas de funcionalidades, comentarios sobre la documentación o cualquier cosa relacionada con Intlayer, usamos esta información para definir nuestra hoja de ruta y mejorar el producto.

      npm install intlayer next-intlayernpx intlayer init
      .├── src│   ├── app│   │   ├── [locale]│   │   │   ├── layout.tsx            # Locale layout for the Intlayer provider│   │   │   ├── page.content.ts│   │   │   └── page.tsx│   │   └── layout.tsx                # Root layout for style and global providers│   ├── components│   │   ├── client-component-example.content.ts│   │   ├── ClientComponentExample.tsx│   │   ├── LocaleSwitcher│   │   │   ├── localeSwitcher.content.ts│   │   │   └── LocaleSwitcher.tsx│   │   ├── server-component-example.content.ts│   │   └── ServerComponentExample.tsx│   └── proxy.ts├── intlayer.config.ts├── next.config.ts├── package.json└── tsconfig.json
      const nextConfig = await withIntlayer(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;
      const nextConfig = withIntlayerSync(nextConfig);const nextConfigWithOtherPlugins = withOtherPlugins(nextConfig);export default nextConfigWithOtherPlugins;
      withRspack(withIntlayer(nextConfig, { enableTurbopack: false }));
      <img src="{content.image.src.value}" alt="{content.image.value}" /><img src="{content.image.src.toString()}" alt="{content.image.toString()}" /><img src="{String(content.image.src)}" alt="{String(content.image)}" />
      import { multipleProxies, intlayerProxy } from "next-intlayer/proxy";import { customProxy } from "@utils/customProxy";export const proxy = multipleProxies([intlayerProxy, customProxy]);
      ```javascript fileName="src/app/[locale]/layout.cjs or src/app/[locale]/page.cjs" codeFormat="commonjs"const { getTranslation, getMultilingualUrls } = require("intlayer");const generateMetadata = async ({ params }) => {  const { locale } = await params;  const t = (content) => getTranslation(content, locale);  return {    title: t({      en: "My title",      fr: "Mon titre",      es: "Mi título",    }),    description: t({      en: "My description",      fr: "Ma description",      es: "Mi descripción",    }),  };};module.exports = { generateMetadata };// ... Resto del código
      "use client";import { useRouter } from "next/navigation";import { useLocale } from "next-intlayer";import { getLocalizedUrl } from "intlayer";// ... Resto del códigoconst router = useRouter();const { setLocale } = useLocale({  onLocaleChange: (locale) => {    router.push(getLocalizedUrl(pathWithoutLocale, locale));  },});return (  <button onClick={() => setLocale(Locales.FRENCH)}>Cambiar a francés</button>);
      "use server";import { getLocale } from "next-intlayer/server";export const myServerAction = async () => {  const locale = await getLocale();  // Hacer algo con la configuración regional};
      npm install @intlayer/swc --save-dev
      {  // ... Tus configuraciones existentes en package.json  "scripts": {    // ... Tus configuraciones existentes de scripts    "dev": "intlayer watch --with 'next dev'",  },}
      npx intlayer extract
      npm install @intlayer/babel --save-dev
      const { intlayerExtractBabelPlugin, getExtractPluginOptions,} = require("@intlayer/babel");module.exports = { presets: ["next/babel"], plugins: [   // Extraer contenido de los componentes en diccionarios   [intlayerExtractBabelPlugin, getExtractPluginOptions()], ],};
      npm run build # O npm run dev
      {  // ... Tus configuraciones existentes de TypeScript  "include": [    // ... Tus configuraciones existentes de TypeScript    ".intlayer/**/*.ts", // Include the auto-generated types  ],}
      # Ignorar los archivos generados por Intlayer.intlayer