Как задать язык документа в React Router v7

Укажите язык страницы для браузеров и экранных читалок

Проблема

Веб-страницы должны явно указывать основной язык для браузеров и вспомогательных технологий. Без явного указания языка экранные читалки используют язык системы пользователя, что может привести к неправильному произношению, если язык контента отличается. Браузеры не могут корректно предлагать перевод, так как им приходится угадывать исходный язык. Поисковым системам сложно правильно индексировать страницы для нужной языковой аудитории, что снижает их видимость для пользователей, ищущих на этом языке.

Решение

Установите атрибут lang на корневой элемент <html>, чтобы объявить основной язык документа. Этот атрибут принимает корректный языковой код, который сообщает браузерам, экранным читалкам и поисковым системам, на каком языке написан контент. При явном указании языка вспомогательные технологии применяют правильные правила произношения, браузеры предлагают подходящие варианты перевода, а поисковые системы индексируют страницу для нужной языковой аудитории.

Шаги

1. Определите текущую локаль

Корневой маршрут в app/root.tsx отвечает за рендеринг корневого HTML-документа. Если ваше приложение использует маршрутизацию по локали (например, паттерны /:locale/...), извлеките локаль из параметров маршрута. В противном случае используйте локаль по умолчанию.

import { useParams } from "react-router";

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";

  return (
    <html lang={locale}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>Content</h1>
      </body>
    </html>
  );
}

Этот код читает локаль из URL, если она указана, и использует английский по умолчанию, если параметр локали отсутствует.

2. Преобразуйте коды локалей в языковые теги

Если ваше приложение использует собственные идентификаторы локалей, отличающиеся от стандартных языковых тегов, создайте функцию для их преобразования в корректные коды языка по стандарту BCP 47.

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    "en-US": "en-US",
    es: "es",
    fr: "fr",
    de: "de",
    ja: "ja",
    "zh-CN": "zh-Hans",
    "zh-TW": "zh-Hant",
  };

  return languageMap[locale] || "en";
}

Это гарантирует, что атрибут lang получает корректный языковой тег, даже если в маршрутизации используются упрощённые коды локалей.

3. Примените языковой тег к элементу HTML

Используйте сопоставленный языковой тег в качестве значения для атрибута lang на элементе <html> в вашем корневом компоненте.

import { useParams } from "react-router";

function getLanguageTag(locale: string): string {
  const languageMap: Record<string, string> = {
    en: "en",
    es: "es",
    fr: "fr",
    de: "de",
  };
  return languageMap[locale] || "en";
}

export default function Root() {
  const params = useParams();
  const locale = params.locale || "en";
  const lang = getLanguageTag(locale);

  return (
    <html lang={lang}>
      <head>
        <meta charSet="utf-8" />
      </head>
      <body>
        <h1>Content</h1>
      </body>
    </html>
  );
}

Теперь атрибут lang отражает текущую локаль и автоматически обновляется при переходе пользователя между маршрутами для разных языков.