Как реализовать маршрутизацию по локали в TanStack Start v1
Настройка маршрутизации с сегментами локали
Проблема
При создании многоязычного приложения один ключевой вопрос определяет всё остальное: как приложение узнает, на каком языке показывать контент? Без явного механизма URL /about становится неоднозначным — он может вести на контент на любом языке. Пользователи не могут делиться ссылками на определённые языковые версии, а поисковым системам сложно понять, какая версия предназначена для какой аудитории. Такая неоднозначность создаёт проблемы и для пользовательского опыта, и для SEO, ведь нет чёткого способа различать языковые варианты одного и того же контента.
Решение
Добавьте идентификатор языка прямо в путь URL, например, /en/about или /fr/about. Это делает каждый путь уникальным для определённого языка, устраняя неоднозначность как для пользователей, так и для поисковых систем. Используя параметр локали в структуре маршрута, каждый URL становится самодокументируемым и удобным для обмена: пользователи могут сохранять или делиться ссылками на контент на нужном языке, а поисковые системы смогут корректно индексировать каждую языковую версию.
Шаги
1. Создайте маршрут с layout для локали
Определите необязательный параметр локали с помощью синтаксиса {-$locale}, чтобы создавать гибкие шаблоны маршрутов, где параметр локали не обязателен. В TanStack Start используется файловая маршрутизация, где маршруты определяются в директории src/routes.
import { createFileRoute, Outlet } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}")({
component: LocaleLayout,
});
function LocaleLayout() {
return <Outlet />;
}
Этот маршрут подходит как для /about (локаль не указана), так и для /en/about (локаль — «en»), что позволяет поддерживать URL-адреса с префиксом локали и без него.
2. Создайте дочерние маршруты внутри макета локали
TanStack Router использует вложенные маршруты, чтобы сопоставлять URL с нужным деревом компонентов для отображения. Создайте файлы маршрутов как дочерние для параметра локали, чтобы наследовать локаль из URL.
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/about")({
component: AboutPage,
});
function AboutPage() {
const { locale } = Route.useParams();
const currentLocale = locale || "en";
return (
<div>
<h1>About Us</h1>
<p>Current locale: {currentLocale}</p>
</div>
);
}
Структура файлов маршрутов {-$locale}/about.tsx создаёт пути вроде /about и /en/about, которые оба отображают один и тот же компонент с доступом к параметру локали.
3. Получите доступ к параметру локали в компонентах
Используйте хук useParams, чтобы считать локаль из URL и определить, какой язык показывать.
import { createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/products")({
component: ProductsPage,
});
function ProductsPage() {
const { locale } = Route.useParams();
const displayLocale = locale || "en";
return (
<div>
<h1>{displayLocale === "fr" ? "Produits" : "Products"}</h1>
</div>
);
}
Если параметр локали не определён, компонент по умолчанию использует базовый язык, что позволяет приложению работать как с локализованными, так и с не локализованными URL.
4. Создайте ссылки с сохранением локали
Используйте компонент Link с параметром локали, чтобы переходить между страницами, сохраняя текущий язык.
import { Link, createFileRoute } from "@tanstack/react-router";
export const Route = createFileRoute("/{-$locale}/")({
component: HomePage,
});
function HomePage() {
const { locale } = Route.useParams();
return (
<nav>
<Link to="/{-$locale}/about" params={{ locale }}>
About
</Link>
<Link to="/{-$locale}/products" params={{ locale }}>
Products
</Link>
</nav>
);
}
Передавая текущую локаль в пропс params, ссылки автоматически формируют URL, соответствующие языковому контексту пользователя, например /fr/about при просмотре французской версии.