Cómo implementar enrutamiento basado en locale en Next.js (Pages Router) v16

Configurar enrutamiento con segmentos de locale

Problema

Al construir una aplicación multilingüe, una decisión fundamental da forma a todo lo demás: ¿cómo sabrá la aplicación qué idioma mostrar? Sin un mecanismo explícito, la URL /about se vuelve ambigua: podría representar contenido en cualquier idioma. Los usuarios no pueden compartir enlaces a versiones en idiomas específicos, y los motores de búsqueda tienen dificultades para entender qué versión pertenece a qué audiencia. Esta ambigüedad crea problemas tanto para la experiencia de usuario como para el SEO, ya que no hay una forma clara de identificar o marcar contenido en un idioma particular.

Solución

Coloca un identificador de idioma directamente en la ruta de la URL configurando el soporte de enrutamiento i18n integrado de Next.js. Declara los locales que deseas soportar y un locale predeterminado en tu configuración de Next.js. Next.js manejará automáticamente el enrutamiento, haciendo que rutas como /fr/about y /nl-NL/about estén disponibles, mientras que el locale predeterminado no tiene prefijo. Esto hace que cada ruta sea única para un idioma específico, eliminando la ambigüedad tanto para usuarios como para motores de búsqueda.

Pasos

1. Añadir configuración i18n a next.config.js

Añade la configuración i18n a tu archivo next.config.js para declarar qué locales soporta tu aplicación.

module.exports = {
  i18n: {
    locales: ["en-US", "fr", "nl-NL"],
    defaultLocale: "en-US",
  },
};

Los locales son identificadores de locale UTS, un formato estandarizado para definir locales, generalmente compuesto por un idioma, región y script separados por un guion. El defaultLocale se utiliza al visitar una ruta sin prefijo de locale.

2. Acceder a información de locale en páginas

Utiliza el hook useRouter() para acceder a información de locale en tus componentes de página.

import { useRouter } from "next/router";

export default function AboutPage() {
  const router = useRouter();
  const { locale, locales, defaultLocale } = router;

  return (
    <div>
      <h1>About Us</h1>
      <p>Current locale: {locale}</p>
    </div>
  );
}

La propiedad locale contiene el locale actualmente activo, locales contiene todos los locales configurados, y defaultLocale contiene el locale predeterminado configurado.

3. Acceder a la configuración regional en funciones de obtención de datos

Al prerenderizar páginas con getStaticProps o getServerSideProps, la información de la configuración regional se proporciona en el contexto.

import { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps = async (context) => {
  const { locale } = context;

  const messages = await import(`../messages/${locale}.json`);

  return {
    props: {
      messages: messages.default,
    },
  };
};

Esto te permite cargar datos específicos de la configuración regional en tiempo de compilación o en tiempo de solicitud según la configuración regional activa.

4. Enlazar entre configuraciones regionales

Usa next/link con una prop locale para cambiar a una configuración regional diferente.

import Link from "next/link";

export default function LanguageSwitcher() {
  return (
    <nav>
      <Link href="/about" locale="en-US">
        English
      </Link>
      <Link href="/about" locale="fr">
        Français
      </Link>
      <Link href="/about" locale="nl-NL">
        Nederlands
      </Link>
    </nav>
  );
}

Si no se proporciona la prop locale, se usa la configuración regional activa actualmente durante las transiciones del cliente. La prop locale permite a los usuarios cambiar de idioma mientras permanecen en la misma página lógica.

5. Generar rutas estáticas para todas las configuraciones regionales

Al aprovechar getStaticPaths, las configuraciones regionales configuradas se proporcionan en el parámetro de contexto bajo locales y la defaultLocale configurada bajo defaultLocale.

import { GetStaticPaths } from "next";

export const getStaticPaths: GetStaticPaths = async (context) => {
  const { locales } = context;

  const paths = locales.flatMap((locale) => [
    { params: { slug: "getting-started" }, locale },
    { params: { slug: "advanced" }, locale },
  ]);

  return {
    paths,
    fallback: false,
  };
};

Esto garantiza que todas las versiones de configuración regional de tus páginas dinámicas se prerrenderizen en tiempo de compilación.