Как определить языковые предпочтения пользователя в Next.js (Pages Router) v16

Автоперенаправление на основе предпочтений браузера

Проблема

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

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

Решение

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

Этот подход использует функцию getServerSideProps из Next.js, которая выполняется на сервере для каждого запроса и может возвращать ответ с перенаправлением. Обрабатывая определение языка на корневом пути, приложение предоставляет интеллектуальный выбор по умолчанию, при этом позволяя пользователям вручную переключать язык позже, если это необходимо.

Шаги

1. Установите библиотеку для разбора заголовка Accept-Language

Заголовок Accept-Language содержит список языковых кодов, разделенных запятыми, с необязательными значениями качества, которые необходимо разобрать. Установите библиотеку для парсинга, чтобы обработать этот формат.

npm install accept-language-parser

Эта библиотека извлекает языковые коды и значения качества из строки заголовка и возвращает их в порядке приоритета.

2. Создайте корневую страницу с логикой перенаправления на стороне сервера

Создайте файл pages/index.tsx, который будет автоматически маршрутизироваться в корневую директорию. Используйте getServerSideProps, чтобы вернуть объект перенаправления с указанием назначения и флага постоянности.

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,
    },
  };
};

Функция getServerSideProps выполняется при каждом запросе, читая заголовок Accept-Language и перенаправляя на соответствующий путь локали до того, как будет отображено содержимое страницы.

3. Определите поддерживаемые локали

Обновите массив SUPPORTED_LOCALES в соответствии с языками, которые поддерживает ваше приложение. Парсер вернет языки в порядке качества, а код выберет первое совпадение.

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

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

4. Обработка случаев отсутствия заголовка Accept-Language

Некоторые запросы могут не содержать заголовок Accept-Language. Код проверяет наличие этого заголовка и использует локаль по умолчанию, если он отсутствует.

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

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

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

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