Как поддерживать локаль в навигационных ссылках в TanStack Start v1
Сохраняйте локаль при внутренней навигации
Проблема
Когда информация о локали кодируется в пути URL, каждая навигационная ссылка должна сохранять эту локаль, чтобы поддерживать единообразный пользовательский опыт. Если пользователь просматривает французскую версию сайта по адресу /fr/products, нажатие на ссылку /about переводит его на язык по умолчанию, нарушая контекст его сессии. Жёсткое кодирование параметров локали в каждую ссылку является повторяющимся и подверженным ошибкам процессом, особенно по мере роста приложения и добавления большего количества ссылок в компоненты.
Без системного подхода к навигации с учётом локали разработчики сталкиваются с выбором: вручную передавать локаль через каждый компонент Link или смириться с тем, что пользователи неожиданно переключаются на язык по умолчанию в середине сессии. Оба варианта ухудшают пользовательский опыт и увеличивают нагрузку на обслуживание.
Решение
Создайте обёрточный компонент вокруг Link фреймворка, который автоматически считывает текущую локаль из URL и добавляет её в проп params каждой навигационной цели. Централизуя эту логику в одном многократно используемом компоненте, все внутренние ссылки наследуют поведение с учётом локали без необходимости вручную передавать параметры локали в каждом месте вызова.
Этот подход работает за счёт считывания активной локали из параметров маршрута с использованием хуков маршрутизатора, а затем добавления этой локали в параметры целевой ссылки. Обёртка сохраняет всю остальную функциональность Link, обеспечивая при этом непрерывность локали при навигации.
Шаги
1. Создайте обёрточный компонент Link с учётом локали
Создайте компонент, который считывает текущую локаль и автоматически включает её в параметры навигации.
import { Link, LinkProps, useParams } from "@tanstack/react-router";
type LocaleLinkProps = LinkProps & {
to: string;
};
export function LocaleLink(props: LocaleLinkProps) {
const params = useParams({ strict: false });
const currentLocale = params.locale;
const enhancedParams = {
...props.params,
...(currentLocale && { locale: currentLocale }),
};
return <Link {...props} params={enhancedParams} />;
}
Этот компонент использует useParams с strict: false для доступа к параметрам из любого маршрута в приложении, извлекает текущую locale и добавляет её в проп params, передаваемый базовому Link. Оператор распространения гарантирует, что любые явно указанные параметры имеют приоритет.
2. Используйте компонент LocaleLink для внутренней навигации
Замените стандартные компоненты Link на LocaleLink по всему вашему приложению.
import { createFileRoute } from "@tanstack/react-router";
import { LocaleLink } from "../components/LocaleLink";
export const Route = createFileRoute("/{-$locale}/products")({
component: ProductsPage,
});
function ProductsPage() {
return (
<div>
<h1>Продукты</h1>
<nav>
<LocaleLink to="/{-$locale}/about">О нас</LocaleLink>
<LocaleLink to="/{-$locale}/contact">Контакты</LocaleLink>
<LocaleLink to="/{-$locale}/products/$id" params={{ id: "123" }}>
Продукт 123
</LocaleLink>
</nav>
</div>
);
}
Когда пользователь посещает /fr/products, все компоненты LocaleLink автоматически перенаправляют на /fr/about, /fr/contact и /fr/products/123. Параметр локали сохраняется без необходимости ручного вмешательства в каждом месте ссылки.
3. Явно обрабатывайте переключение локали, когда это необходимо
Для компонентов переключателя языка обойдите автоматическую вставку локали, используя стандартный компонент Link напрямую.
import { Link, useParams } from "@tanstack/react-router";
export function LanguageSwitcher() {
const params = useParams({ strict: false });
const currentPath = window.location.pathname.replace(/^\/(en|fr|es)/, "");
return (
<div>
<Link to={`/{-$locale}${currentPath}`} params={{ locale: "en" }}>
English
</Link>
<Link to={`/{-$locale}${currentPath}`} params={{ locale: "fr" }}>
Français
</Link>
<Link to={`/{-$locale}${currentPath}`} params={{ locale: "es" }}>
Español
</Link>
</div>
);
}
Переключатели языка требуют явного управления параметром локали, поэтому они используют стандартный компонент Link и явно задают параметр locale. Это позволяет пользователям менять язык, оставаясь на той же логической странице.