Comenzando a internacionalizar (i18n) con Intlayer y Next.js 15 App Router
¿Qué es Intlayer?
Intlayer es una innovadora biblioteca de internacionalización (i18n) de código abierto diseñada para simplificar el soporte multilingüe en aplicaciones web modernas. Intlayer se integra sin problemas con el último framework Next.js 15, incluyendo su potente App Router. Está optimizado para trabajar con Componentes del Servidor para un renderizado eficiente y es completamente compatible con Turbopack.
Con Intlayer, puedes:
- Gestionar traducciones fácilmente utilizando 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.
- Asegurar soporte de TypeScript con tipos autogenerados, mejorando la autocompletación y la detección de errores.
- Beneficiarte de características avanzadas, como la detección y cambio dinámico de locales.
Intlayer es compatible con Next.js 12, 13, 14 y 15. Si estás utilizando Next.js Page Router, 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:
npm install intlayer next-intlayer
intlayer
El paquete principal que proporciona herramientas de internacionalización para la gestión de configuraciones, traducción, declaración de contenido, transpilation, y comandos CLI.
next-intlayer
El paquete que integra Intlayer con Next.js. Proporciona proveedores de contexto y hooks para la internacionalización de Next.js. Además, incluye el plugin de Next.js para integrar Intlayer con Webpack o Turbopack, así como middleware para detectar el locale preferido del usuario, gestionar cookies y manejar redirecciones de URL.
Paso 2: Configurar Tu Proyecto
Crea un archivo de configuración para configurar los idiomas de tu aplicación:
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 middleware, 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 parámetros disponibles, consulta la documentación de configuración.
Paso 3: Integrar Intlayer en Tu Configuración de Next.js
Configura tu instalación de Next.js para usar Intlayer:
import { withIntlayer } from "next-intlayer/server";
/** @type {import('next').NextConfig} */
const nextConfig = {};
export default withIntlayer(nextConfig);
El plugin de Next.js withIntlayer() se utiliza para integrar Intlayer con Next.js. Asegura la construcción de archivos de declaración de contenido y los monitorea 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 asegurar la compatibilidad con componentes del servidor.
Paso 4: Configurar Middleware para la Detección de Locales
Configura middleware para detectar el locale preferido del usuario:
export { intlayerMiddleware as middleware } from "next-intlayer/middleware";
export const config = {
matcher:
"/((?!api|static|assets|robots|sitemap|sw|service-worker|manifest|.*\\..*|_next).*)",
};
El intlayerMiddleware se utiliza para detectar el locale preferido del usuario y redirigirlo a la URL apropiada según lo especificado en la configuración. Además, permite guardar el locale preferido del usuario en una cookie.
Paso 5: Definir Rutas de Locales Dinámicas
Elimina todo de RootLayout y reemplázalo con el siguiente código:
import type { PropsWithChildren, FC } from "react";
import "./globals.css";
const RootLayout: FC<PropsWithChildren> = ({ children }) => children;
export default RootLayout;
Mantener el componente RootLayout vacío permite establecer los atributos lang y dir en la etiqueta <html>.
Para implementar enrutamiento dinámico, proporciona la ruta para el locale agregando un nuevo layout en tu directorio [locale]:
import type { NextLayoutIntlayer } 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}>{children}</body>
</html>
);
};
export default LocaleLayout;
El segmento de ruta [locale] se utiliza para definir el locale. Ejemplo: /en-US/about se referirá a en-US y /fr/about a fr.
Luego, implementa la función generateStaticParams en el Layout de tu aplicación.
export { generateStaticParams } from "next-intlayer"; // Línea a 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 la computación en tiempo de ejecución y mejorando la experiencia del usuario. Para más detalles, consulta la documentación de Next.js sobre generateStaticParams.
Paso 6: Declarar Tu Contenido
Crea y gestiona tus declaraciones de contenido para almacenar traducciones:
import { t, type DeclarationContent } 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 DeclarationContent;
export default pageContent;
Tus declaraciones de contenido pueden ser definidas en cualquier lugar 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.{ts,tsx,js,jsx,mjs,cjs}). Para más detalles, consulta la documentación de declaración de contenido.
Paso 7: Utilizar Contenido en Tu Código
Accede a tus diccionarios de contenido en toda tu aplicación:
import type { FC } from "react";
import { ClientComponentExample } from "@components/ClientComponentExample";
import { ServerComponentExample } from "@components/ServerComponentExample";
import { type NextPageIntlayer, IntlayerClientProvider } from "next-intlayer";
import { IntlayerServerProvider, useIntlayer } from "next-intlayer/server";
const PageContent: FC = () => {
const { title, 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 />
<IntlayerClientProvider locale={locale}>
<ClientComponentExample />
</IntlayerClientProvider>
</IntlayerServerProvider>
</>
);
};
export default Page;
- IntlayerClientProvider se utiliza para proporcionar el locale a los componentes del lado del cliente. Se puede colocar en cualquier componente padre, incluyendo el layout. Sin embargo, se recomienda colocarlo en un layout porque Next.js comparte el código del layout entre las 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 usa para proporcionar el locale a los hijos del servidor. No se puede establecer 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 almacenamiento de datos por solicitud (a través del mecanismo de caché de React), haciendo que cada “contexto” se recree para diferentes segmentos de la aplicación. Colocar el proveedor en un layout compartido rompería esta separación, impidiendo la correcta propagación de los valores de contexto del servidor hacia tus componentes del servidor.
"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>
);
};
import type { FC } from "react";
import { useIntlayer } from "next-intlayer/server";
export const ServerComponentExample: FC = () => {
const content = useIntlayer("server-component-example"); //
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