Связывание между локализованными страницами
Сохраняем выбранный пользователем язык
Проблема
Когда коды языков входят в состав URL, создание внутренних ссылок становится сложнее. Простая ссылка вроде <a href="/about"> будет некорректной, так как нарушает локализованный маршрут и отправляет пользователя с /fr/contact на /about вместо /fr/about. В итоге пользователь теряет выбранный язык.
Решение
Создайте свой обёрточный компонент вокруг стандартного компонента Next.js Link. Новый компонент будет использовать хук 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;
// Check if href is a string and needs prefixing
if (typeof href === 'string' && href.startsWith('/')) {
localizedHref = `/${lang}${href}`;
} else if (
typeof href === 'object' &&
href !== null &&
href.pathname?.startsWith('/')
) {
// Re-create the object with a prefixed pathname
localizedHref = {
...href,
pathname: `/${lang}${href.pathname}`,
};
}
// Absolute URLs or other cases are passed through
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>Home page</h1>
<p>Current language: {params.lang}</p>
<nav>
<ul>
<li>
{/* This will render as /en/about or /es/about, etc. */}
<LocalizedLink href="/about">About page</LocalizedLink>
</li>
<li>
{/* This also works */}
<LocalizedLink href={{ pathname: '/contact' }}>
Contact page
</LocalizedLink>
</li>
</ul>
</nav>
</div>
);
}
Теперь при использовании <LocalizedLink href="/about"> ссылка корректно ведёт на /{current_lang}/about, и пользователь остаётся на выбранном языке при навигации по сайту.