在本地化页面之间链接
确保用户保持在其选择的语言中
问题
当语言代码是 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;
// 检查 href 是否是字符串并需要添加前缀
if (typeof href === 'string' && href.startsWith('/')) {
localizedHref = `/${lang}${href}`;
} else if (
typeof href === 'object' &&
href !== null &&
href.pathname?.startsWith('/')
) {
// 重新创建带有前缀路径名的对象
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,确保用户在浏览您的网站时保持在其选择的语言中。