Как сохранять локаль в навигационных ссылках в 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>
  );
}

Этот компонент считывает активную локаль из маршрутизатора, делая её доступной для использования в логике навигации.

Если свойство локали не указано для 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>
  );
}

Как статические, так и динамические маршруты автоматически включают текущий префикс локали, сохраняя выбранный пользователем язык при навигации по приложению.