Связывание между локализованными страницами
Сохранение пользователей на выбранном языке
Проблема
Когда языковые коды являются частью URL, создание внутренних ссылок становится сложным. Простая ссылка, такая как <a href="/about">, является неправильной, так как она нарушает локализованный маршрут, отправляя пользователя с /fr/contact на /about вместо /fr/about. Это выводит пользователя из выбранного языка.
Решение
Создайте пользовательский обёрточный компонент вокруг компонента Link из Next.js. Этот новый компонент будет использовать хук useParams для получения текущего языка из URL и автоматически добавлять его к любому href, который он получает, гарантируя, что все внутренние ссылки правильно локализованы.
Шаги
1. Создайте компонент LocalizedLink
Создайте новый файл 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, сохраняя пользователя в выбранном языке при навигации по вашему сайту.