Как сохранять локаль в навигационных ссылках в Next.js (Pages Router) v16
Сохранение локали при внутренней навигации
Проблема
Когда веб-приложение кодирует языковые предпочтения в пути URL, каждая внутренняя ссылка должна сохранять этот языковой контекст на протяжении всей сессии пользователя. Без явной обработки локали ссылки, написанные как простые пути, могут случайно терять языковой префикс, из-за чего пользователи теряют выбранный язык во время навигации. Это нарушает локализованный опыт и заставляет пользователей многократно выбирать предпочитаемый язык.
Решение
Убедитесь, что каждая внутренняя ссылка для навигации автоматически включает текущую локаль, считывая её из контекста маршрутизатора. Pages Router в Next.js предоставляет встроенную поддержку локалей через свою систему маршрутизации, где активная локаль доступна через хук useRouter. По умолчанию компонент Link сохраняет текущую локаль во время клиентских переходов, но понимание этого поведения и его последовательное применение по всему приложению обеспечивает бесшовную навигацию с учётом локали.
Шаги
1. Получите текущую локаль из маршрутизатора
Хук useRouter предоставляет locale (текущую активную локаль), locales (все настроенные локали) и defaultLocale (настроенную локаль по умолчанию).
import { useRouter } from "next/router";
export default function Navigation() {
const router = useRouter();
const currentLocale = router.locale;
return (
<nav>
<p>Текущая локаль: {currentLocale}</p>
</nav>
);
}
Этот компонент считывает активную локаль из маршрутизатора, делая её доступной для использования в логике навигации.
2. Используйте компоненты Link без явных свойств локали
Если свойство локали не указано для Link, то текущая активная локаль используется во время клиентских переходов.
import Link from "next/link";
export default function Navigation() {
return (
<nav>
<Link href="/about">О нас</Link>
<Link href="/products">Продукты</Link>
<Link href="/contact">Контакты</Link>
</nav>
);
}
Эти ссылки автоматически сохраняют текущую локаль. Если пользователь просматривает /fr/products, нажатие на "О нас" перенаправит на /fr/about.
3. Создайте помощник для ссылок с учетом локали для явного управления
В случаях, когда требуется явное управление или вы хотите сделать обработку локали более очевидной, создайте обертку-компонент, которая явно передает текущую локаль.
import Link from "next/link";
import { useRouter } from "next/router";
import { ReactNode } from "react";
interface LocaleLinkProps {
href: string;
children: ReactNode;
}
export function LocaleLink({ href, children }: LocaleLinkProps) {
const { locale } = useRouter();
return (
<Link href={href} locale={locale}>
{children}
</Link>
);
}
Этот компонент делает сохранение локали явным и может быть расширен дополнительной логикой, связанной с локалью, если это необходимо.
4. Обрабатывайте программную навигацию с сохранением локали
При использовании методов маршрутизатора напрямую вы можете указать локаль через параметры перехода или сохранить всю информацию о маршрутизации, включая локаль, передав параметр href как объект.
import { useRouter } from "next/router";
export default function NavigationButton() {
const router = useRouter();
const { pathname, asPath, query, locale } = router;
const handleNavigate = () => {
router.push({ pathname: "/dashboard", query }, asPath, { locale });
};
return <button onClick={handleNavigate}>Перейти к панели управления</button>;
}
Этот шаблон гарантирует, что программная навигация сохраняет текущую локаль и любые существующие параметры запроса.
5. Применяйте единообразные шаблоны ссылок по всему приложению
Используйте стандартный компонент Link во всем приложении, полагаясь на его встроенное поведение сохранения локали.
import Link from "next/link";
export default function ProductCard({ productId }: { productId: string }) {
return (
<article>
<h2>Продукт {productId}</h2>
<Link href={`/products/${productId}`}>Посмотреть детали</Link>
<Link href="/products">Назад к продуктам</Link>
</article>
);
}
Как статические, так и динамические маршруты автоматически включают текущий префикс локали, сохраняя выбранный пользователем язык при навигации по приложению.