Как реализовать маршрутизацию по локали в React Router v7
Настройте маршрутизацию с сегментами локали
Проблема
При создании многоязычного приложения один ключевой вопрос определяет всё остальное: как приложение узнает, на каком языке показывать контент? Без явного механизма URL /about становится неоднозначным — он может вести на контент на любом языке. Пользователи не могут делиться ссылками на конкретные языковые версии, а поисковым системам сложно понять, какая версия предназначена для какой аудитории. Такая неоднозначность мешает и пользовательскому опыту, и поисковой оптимизации.
Решение
Добавьте идентификатор языка прямо в путь URL, например, /en/about или /fr/about. Это делает каждый путь уникальным для определённого языка, устраняя неоднозначность как для пользователей, так и для поисковых систем. Если определить маршруты с параметром локали в качестве первого сегмента, приложение сможет извлекать локаль из URL и использовать её для выбора языка контента. Такой подход гарантирует, что каждый URL однозначно определяет и страницу, и язык.
Шаги
1. Определите маршруты с параметром локали
Настройте маршруты в app/routes.ts, чтобы параметр локали был первым сегментом каждого пути.
import { type RouteConfig, route, index } from "@react-router/dev/routes";
export default [
route(":locale", "./localized-layout.tsx", [
index("./home.tsx"),
route("about", "./about.tsx"),
route("contact", "./contact.tsx"),
]),
] satisfies RouteConfig;
Префикс с двоеточием делает locale динамическим сегментом, который будет извлекаться из URL и передаваться как параметр в компоненты маршрута. Такая конфигурация создаёт маршруты вроде /en, /en/about, /fr/contact, где первый сегмент всегда — локаль.
2. Создайте layout-компонент для извлечения локали
Дочерние маршруты отображаются через компонент Outlet в родительском маршруте. Создайте layout, который извлекает параметр locale и рендерит вложенные маршруты.
import { Outlet, useParams } from "react-router";
export default function LocalizedLayout() {
const { locale } = useParams();
return (
<div>
<nav>
<a href={`/${locale}`}>Home</a>
<a href={`/${locale}/about`}>About</a>
<a href={`/${locale}/contact`}>Contact</a>
</nav>
<Outlet />
</div>
);
}
Хук useParams получает значение динамического сегмента из URL. Layout использует этот locale для построения навигационных ссылок и передаёт управление рендерингом дочерним маршрутам через Outlet.
3. Доступ к locale в компонентах страниц
Используйте хук useParams в любом компоненте маршрута, чтобы получить параметр locale.
import { useParams } from "react-router";
export default function About() {
const { locale } = useParams();
return (
<div>
<h1>About Us</h1>
<p>Current locale: {locale}</p>
</div>
);
}
Каждый компонент, отображаемый внутри локализованного layout, может извлекать locale из URL. Это значение можно использовать для загрузки нужных переводов, форматирования дат и чисел или других решений, зависящих от локали.
4. Используйте компоненты Link для навигации на клиенте
Замените теги anchor на компоненты Link, чтобы включить навигацию с помощью клиентского роутинга.
import { Outlet, useParams, Link } from "react-router";
export default function LocalizedLayout() {
const { locale } = useParams();
return (
<div>
<nav>
<Link to={`/${locale}`}>Home</Link>
<Link to={`/${locale}/about`}>About</Link>
<Link to={`/${locale}/contact`}>Contact</Link>
</nav>
<Outlet />
</div>
);
}
Компонент Link обрабатывает роутинг на стороне клиента и предотвращает перезагрузку страницы, обеспечивая плавную навигацию между страницами. Каждый линк включает параметр locale, чтобы сохранять языковой контекст при переходах.