Cómo detectar las preferencias de idioma del usuario en Next.js (Pages Router) v16

Redirección automática basada en las preferencias del navegador

Problema

Cada navegador envía una cabecera Accept-Language con cada solicitud HTTP, indicando los idiomas preferidos del usuario en orden de prioridad. La mayoría de las aplicaciones ignoran esta valiosa señal y sirven un idioma predeterminado a todos los visitantes, obligando a los usuarios a buscar manualmente un selector de idioma incluso cuando la aplicación ya conoce sus preferencias. Esto crea fricción innecesaria durante la primera visita y puede llevar a que los usuarios abandonen el sitio antes de encontrar contenido en su idioma.

Cuando los usuarios llegan a la ruta raíz de una aplicación, existe la oportunidad de examinar sus preferencias de idioma y dirigirlos inmediatamente a contenido en un idioma que comprendan. Sin esta detección, los usuarios internacionales se enfrentan a una experiencia en inglés independientemente de la configuración de su navegador, perdiendo la oportunidad de proporcionar una primera impresión acogedora y localizada.

Solución

Crea una página raíz que ejecute lógica del lado del servidor en cada solicitud a la ruta raíz. Lee la cabecera HTTP Accept-Language de la solicitud entrante y analízala para extraer el idioma más preferido del usuario. Compara este idioma con la lista de idiomas que tu aplicación soporta. Si se encuentra una coincidencia, redirige al usuario a la ruta raíz de ese idioma. Si ningún idioma soportado coincide, redirige a una ruta de idioma predeterminada.

Este enfoque aprovecha la función getServerSideProps de Next.js, que se ejecuta en el servidor para cada solicitud y puede devolver una respuesta de redirección. Al manejar la detección en la ruta raíz, la aplicación proporciona un valor predeterminado inteligente mientras permite a los usuarios cambiar manualmente de idioma más tarde si es necesario.

Pasos

1. Instalar una biblioteca para analizar el encabezado Accept-Language

El encabezado Accept-Language contiene una lista separada por comas de códigos de idioma con valores de calidad opcionales que deben analizarse. Instala una biblioteca de análisis para manejar este formato.

npm install accept-language-parser

Esta biblioteca extrae códigos de idioma y puntuaciones de calidad de la cadena del encabezado y los devuelve en orden de prioridad.

2. Crear una página raíz con lógica de redirección del lado del servidor

Crea un archivo pages/index.tsx que se enrutará automáticamente al directorio raíz. Usa getServerSideProps para devolver un objeto de redirección con un destino y un indicador permanente.

import { GetServerSideProps } from "next";
import parser from "accept-language-parser";

const SUPPORTED_LOCALES = ["en", "fr", "es", "de"];
const DEFAULT_LOCALE = "en";

export default function RootPage() {
  return null;
}

export const getServerSideProps: GetServerSideProps = async (context) => {
  const acceptLanguageHeader = context.req.headers["accept-language"];

  let targetLocale = DEFAULT_LOCALE;

  if (acceptLanguageHeader) {
    const languages = parser.parse(acceptLanguageHeader);

    const matchedLanguage = languages.find((lang) =>
      SUPPORTED_LOCALES.includes(lang.code),
    );

    if (matchedLanguage) {
      targetLocale = matchedLanguage.code;
    }
  }

  return {
    redirect: {
      destination: `/${targetLocale}`,
      permanent: false,
    },
  };
};

La función getServerSideProps se ejecuta en cada solicitud, leyendo el encabezado Accept-Language y redirigiendo a la ruta de configuración regional apropiada antes de que se renderice cualquier contenido de página.

3. Definir las configuraciones regionales compatibles

Actualiza el array SUPPORTED_LOCALES para que coincida con los idiomas que admite tu aplicación. El analizador devolverá los idiomas en orden de calidad, y el código selecciona la primera coincidencia.

const SUPPORTED_LOCALES = ["en", "fr", "es", "de", "ja", "zh"];
const DEFAULT_LOCALE = "en";

El analizador devuelve los idiomas ordenados por calidad de mayor a menor, por lo que el primer idioma compatible encontrado representa la preferencia más fuerte del usuario que tu aplicación puede satisfacer.

4. Manejar casos sin encabezado Accept-Language

Algunas solicitudes pueden no incluir un encabezado Accept-Language. El código verifica la presencia del encabezado y recurre a la configuración regional predeterminada cuando falta.

if (acceptLanguageHeader) {
  const languages = parser.parse(acceptLanguageHeader);

  const matchedLanguage = languages.find((lang) =>
    SUPPORTED_LOCALES.includes(lang.code),
  );

  if (matchedLanguage) {
    targetLocale = matchedLanguage.code;
  }
}

Esto garantiza que la aplicación siempre redirija a una ruta de configuración regional válida, incluso cuando la información del idioma del navegador no esté disponible.