在本地化页面之间链接

确保用户保持在其选择的语言中

问题

当语言代码是 URL 的一部分时,创建内部链接会变得复杂。像 <a href="/about"> 这样简单的链接是错误的,因为它会破坏本地化路由,将用户从 /fr/contact 发送到 /about,而不是 /fr/about。这会使用户脱离他们选择的语言。

解决方案

围绕 Next.js 的 Link 组件创建一个自定义的包装组件。这个新组件将使用 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('/')
  ) {
    // 重新创建带有前缀路径名的对象
    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,确保用户在浏览您的网站时保持在其选择的语言中。