Связывание между локализованными страницами

Сохранение пользователей на выбранном языке

Проблема

Когда языковые коды являются частью URL, создание внутренних ссылок становится сложным. Простая ссылка, такая как <a href="/about">, является неправильной, так как она нарушает локализованный маршрут, отправляя пользователя с /fr/contact на /about вместо /fr/about. Это выводит пользователя из выбранного языка.

Решение

Создайте пользовательский обёрточный компонент вокруг компонента Link из Next.js. Этот новый компонент будет использовать хук useParams для получения текущего языка из URL и автоматически добавлять его к любому href, который он получает, гарантируя, что все внутренние ссылки правильно локализованы.

Шаги

Создайте новый файл app/components/LocalizedLink.tsx. Этот компонент должен быть клиентским, чтобы использовать хук useParams.

// app/components/LocalizedLink.tsx
'use client';

import Link from 'next/link';
import { useParams } from 'next/navigation';
import type { ComponentProps } from 'react';

type LinkProps = ComponentProps<typeof Link>;

export default function LocalizedLink({ href, ...rest }: LinkProps) {
  const params = useParams();
  const lang = params.lang as string;

  let localizedHref = href;

  // Проверяем, является ли href строкой и нуждается ли в добавлении префикса
  if (typeof href === 'string' && href.startsWith('/')) {
    localizedHref = `/${lang}${href}`;
  } else if (
    typeof href === 'object' &&
    href !== null &&
    href.pathname?.startsWith('/')
  ) {
    // Воссоздаём объект с добавленным префиксом в pathname
    localizedHref = {
      ...href,
      pathname: `/${lang}${href.pathname}`,
    };
  }
  // Абсолютные URL или другие случаи передаются без изменений

  return <Link href={localizedHref} {...rest} />;
}

Этот компонент импортирует стандартные свойства Link. Он проверяет, является ли href строкой (например, /about) или объектом (например, { pathname: '/about' }) и интеллектуально добавляет текущий lang (например, es) к нему.

2. Используйте компонент на своих страницах

Теперь на своих страницах импортируйте LocalizedLink вместо стандартного next/link. Вы можете использовать его так же, как обычный компонент Link, но без необходимости беспокоиться о языковом префиксе.

// app/[lang]/page.tsx
import LocalizedLink from '@/app/components/LocalizedLink';

export default function Home({ params }: { params: { lang: string } }) {
  return (
    <div>
      <h1>Главная страница</h1>
      <p>Текущий язык: {params.lang}</p>
      
      <nav>
        <ul>
          <li>
            {/* Это будет отображаться как /en/about или /es/about и т.д. */}
            <LocalizedLink href="/about">Страница "О нас"</LocalizedLink>
          </li>
          <li>
            {/* Это тоже работает */}
            <LocalizedLink href={{ pathname: '/contact' }}>
              Страница "Контакты"
            </LocalizedLink>
          </li>
        </ul>
      </nav>
    </div>
  );
}

Использование <LocalizedLink href="/about"> теперь корректно создаёт ссылку на /{current_lang}/about, сохраняя пользователя в выбранном языке при навигации по вашему сайту.