Как определить языковые предпочтения пользователя в TanStack Start v1
Автоматическое перенаправление на основе предпочтений браузера
Проблема
Веб-браузеры отправляют заголовок Accept-Language с каждым HTTP-запросом, указывая предпочтительные языки пользователя в порядке приоритета. Этот заголовок предоставляет ценную информацию о том, на каком языке пользователю удобнее всего работать, однако многие приложения полностью его игнорируют. Вместо этого они показывают язык по умолчанию — обычно английский — всем посетителям, независимо от их реальных предпочтений. Пользователям приходится вручную искать переключатель языка, создавая ненужные трудности, хотя приложение уже располагает информацией для более удачного первоначального выбора.
Эта упущенная возможность персонализации особенно раздражает пользователей, не говорящих на английском, которые явно настроили языковые предпочтения в своем браузере. В результате создается плохое первое впечатление и дополнительные шаги, прежде чем пользователи смогут взаимодействовать с контентом на предпочитаемом языке.
Решение
Перехватывайте запросы к корневому пути и анализируйте заголовок Accept-Language, чтобы определить предпочтительный язык пользователя. Разберите заголовок, чтобы извлечь язык с наивысшим приоритетом, который поддерживает ваше приложение. Если совпадение найдено, перенаправьте пользователя на соответствующий локализованный маршрут. Если в заголовке не найдено поддерживаемого языка, выполните перенаправление на язык по умолчанию.
Этот подход автоматически учитывает предпочтения пользователя, сохраняя при этом четкую структуру URL, где для каждого языка используется собственный префикс пути. Перенаправление выполняется на стороне сервера до рендеринга страницы, что гарантирует, что пользователи сразу попадают на контент на предпочитаемом языке, не видя вспышки неправильного языка.
Шаги
1. Создайте вспомогательную функцию для разбора заголовка Accept-Language
Заголовок Accept-Language содержит языковые коды с необязательными значениями качества, которые указывают порядок предпочтений. Создайте парсер, который извлекает эти языки, сортирует их по приоритету и находит первое совпадение из списка поддерживаемых языков.
export function parseAcceptLanguage(
header: string | null,
supportedLocales: string[],
): string | null {
if (!header) {
return null;
}
const languages = header
.split(",")
.map((lang) => {
const [code, qValue] = lang.trim().split(";q=");
const quality = qValue ? parseFloat(qValue) : 1.0;
return { code: code.toLowerCase(), quality };
})
.sort((a, b) => b.quality - a.quality);
for (const { code } of languages) {
const exactMatch = supportedLocales.find(
(locale) => locale.toLowerCase() === code,
);
if (exactMatch) {
return exactMatch;
}
const baseCode = code.split("-")[0];
const baseMatch = supportedLocales.find((locale) =>
locale.toLowerCase().startsWith(baseCode),
);
if (baseMatch) {
return baseMatch;
}
}
return null;
}
Эта функция разделяет заголовок по запятым, извлекает значения качества, сортирует по приоритету и проверяет как точные совпадения, так и совпадения по базовому языку с вашими поддерживаемыми локалями.
2. Определите поддерживаемые локали
Создайте конфигурацию, которая перечисляет все языки, поддерживаемые вашим приложением, и указывает, какой из них использовать в качестве стандартного резервного.
export const SUPPORTED_LOCALES = ["en", "fr", "de", "es", "ja"];
export const DEFAULT_LOCALE = "en";
Эти константы централизуют вашу языковую конфигурацию и упрощают добавление или удаление поддерживаемых языков по мере роста вашего приложения.
3. Создайте обработчик маршрута сервера для корневого пути
Добавьте серверный обработчик GET для вашего индексного маршрута, который считывает заголовок Accept-Language, определяет лучшую локаль и перенаправляет пользователя на соответствующий языковой маршрут.
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";
export const Route = createFileRoute("/")({
server: {
handlers: {
GET: async () => {
const headers = getRequestHeaders();
const acceptLanguage = headers.get("accept-language");
const preferredLocale = parseAcceptLanguage(
acceptLanguage,
SUPPORTED_LOCALES,
);
const targetLocale = preferredLocale || DEFAULT_LOCALE;
throw redirect({
to: `/${targetLocale}`,
statusCode: 302,
});
},
},
},
});
Этот обработчик запускается на сервере, когда пользователь посещает корневой путь, анализирует его языковые предпочтения и немедленно перенаправляет его на маршрут с наиболее подходящей локалью до выполнения любого клиентского кода.
4. Импортируйте вспомогательную функцию
Убедитесь, что вспомогательная функция parse доступна в вашем файле маршрута, импортировав её в начале вместе с вашей конфигурацией локалей.
import { createFileRoute, redirect } from "@tanstack/react-router";
import { getRequestHeaders } from "@tanstack/react-start/server";
import {
parseAcceptLanguage,
SUPPORTED_LOCALES,
DEFAULT_LOCALE,
} from "../lib/locale";
Разместите функцию parseAcceptLanguage и константы локалей в общем модуле, чтобы их можно было повторно использовать в вашем приложении, если это необходимо.