Cómo marcar contenido en múltiples idiomas en Next.js (Pages Router) v16

Marcar texto en diferentes idiomas para accesibilidad

Problema

Cuando una página contiene texto en múltiples idiomas, los navegadores y las tecnologías de asistencia tratan todo el contenido como si perteneciera al idioma principal de la página. Un lector de pantalla configurado para inglés intentará pronunciar frases en francés, títulos de libros en español o nombres de empresas en alemán utilizando la fonética inglesa, produciendo un resultado ininteligible para los usuarios que dependen del audio. Los navegadores aplican reglas de corrección ortográfica y tipografía basadas en el idioma incorrecto, marcando palabras extranjeras correctamente escritas como errores y manejando incorrectamente las convenciones de puntuación y formato específicas de cada idioma.

Esto crea barreras para los usuarios con discapacidades visuales que dependen de una pronunciación precisa, y degrada la experiencia para todos los usuarios al introducir ruido visual por advertencias incorrectas de corrección ortográfica y renderizado inadecuado del texto.

Solución

Aplicar el atributo HTML lang a los elementos que contienen texto en idioma extranjero, declarando explícitamente el idioma de ese contenido. Este atributo indica a los navegadores y tecnologías de asistencia que el texto marcado debe procesarse utilizando las reglas de su idioma declarado en lugar del idioma principal de la página. Los lectores de pantalla cambian al motor de pronunciación apropiado, los navegadores aplican los diccionarios de corrección ortográfica correctos, y los motores tipográficos utilizan reglas de formato específicas del idioma.

Al envolver el texto extranjero en elementos con el atributo lang correcto, creas límites claros de idioma dentro de tu contenido que preservan la integridad del texto multilingüe.

Pasos

1. Crear un componente de texto marcado con idioma

Construye un componente React que envuelva el contenido en idioma extranjero en un elemento span con el atributo lang apropiado.

interface ForeignTextProps {
  lang: string;
  children: React.ReactNode;
}

export function ForeignText({ lang, children }: ForeignTextProps) {
  return <span lang={lang}>{children}</span>;
}

Este componente acepta un código de idioma y envuelve sus hijos en un span con el atributo lang establecido, creando un límite de idioma que las tecnologías de asistencia y los navegadores pueden reconocer.

2. Utiliza el componente para marcar frases extranjeras

Envuelve el texto en idioma extranjero dentro de tu contenido utilizando el componente, especificando el código de idioma ISO 639-1 apropiado.

export default function ArticlePage() {
  return (
    <article>
      <h1>Entendiendo la cocina francesa</h1>
      <p>
        El concepto de <ForeignText lang="fr">mise en place</ForeignText> es
        fundamental para la cocina profesional. Significa tener todos los ingredientes
        preparados y organizados antes de comenzar.
      </p>
      <p>
        El restaurante <ForeignText lang="fr">Le Bernardin</ForeignText> en
        Nueva York ha mantenido tres estrellas Michelin durante décadas.
      </p>
    </article>
  );
}

Cada frase extranjera está envuelta en el componente con su código de idioma, asegurando que los lectores de pantalla la pronuncien correctamente y que los navegadores apliquen las reglas lingüísticas apropiadas.

3. Maneja pasajes más largos en idioma extranjero

Para contenido extranjero de múltiples oraciones, envuelve todo el pasaje en un solo elemento marcado con el idioma para evitar fragmentar el contexto lingüístico.

export default function QuotePage() {
  return (
    <article>
      <h1>Declaración Universal de Derechos Humanos</h1>
      <h2>Artículo 1</h2>
      <blockquote lang="es">
        <p>
          Todos los seres humanos nacen libres e iguales en dignidad y derechos
          y, dotados como están de razón y conciencia, deben comportarse
          fraternalmente los unos con los otros.
        </p>
      </blockquote>
    </article>
  );
}

Aplicar lang directamente a elementos de nivel de bloque como blockquote o p marca todo el pasaje, permitiendo que los lectores de pantalla mantengan una pronunciación consistente y que los navegadores apliquen reglas lingüísticas al contexto completo.

4. Marca texto extranjero en mensajes formateados

Cuando aparece contenido en idioma extranjero dentro de mensajes traducidos, utiliza el componente dentro del formato de texto enriquecido del mensaje.

import { FormattedMessage } from "react-intl";

export default function RecipePage() {
  return (
    <div>
      <FormattedMessage
        id="recipe.description"
        defaultMessage="Este plato se llama {dishName} en la cocina francesa."
        values={{
          dishName: <ForeignText lang="fr">coq au vin</ForeignText>,
        }}
      />
    </div>
  );
}

El componente se integra con el formato de texto enriquecido de react-intl, permitiéndote marcar términos extranjeros dentro del contenido traducido mientras preservas los límites lingüísticos para las tecnologías de asistencia.

5. Crear variantes para énfasis semántico

Extiende el patrón para usar elementos HTML semánticos cuando el texto en idioma extranjero también requiere énfasis o estilo idiomático.

interface ForeignEmphasisProps {
  lang: string;
  children: React.ReactNode;
}

export function ForeignEmphasis({ lang, children }: ForeignEmphasisProps) {
  return <i lang={lang}>{children}</i>;
}

El elemento i representa semánticamente texto en una voz o estado de ánimo alternativo, haciéndolo apropiado para términos extranjeros que también se distinguen del texto circundante. El atributo lang asegura la pronunciación correcta mientras que el elemento proporciona significado semántico.

6. Documentar los códigos de idioma soportados

Crea un tipo o constante que defina los códigos de idioma que tu aplicación soporta para asegurar consistencia y detectar errores durante el desarrollo.

export const SUPPORTED_LANGUAGES = {
  FRENCH: "fr",
  SPANISH: "es",
  GERMAN: "de",
  ITALIAN: "it",
  JAPANESE: "ja",
  CHINESE: "zh",
} as const;

type LanguageCode =
  (typeof SUPPORTED_LANGUAGES)[keyof typeof SUPPORTED_LANGUAGES];

interface ForeignTextProps {
  lang: LanguageCode | string;
  children: React.ReactNode;
}

export function ForeignText({ lang, children }: ForeignTextProps) {
  return <span lang={lang}>{children}</span>;
}

Definir los idiomas soportados como constantes proporciona autocompletado en tu editor y documenta qué códigos de idioma se utilizan en toda tu aplicación, mientras que aún permite códigos de idioma arbitrarios cuando sea necesario.