构建语言切换器

允许用户在任何页面切换语言

问题

用户位于特定页面,例如 /en/products/123,并希望查看相同页面的其他语言版本。点击语言切换器(例如“Français”)通常会将他们带回主页(/fr/),而不是对应的产品页面,从而中断了他们的工作流程,并迫使他们重新导航。

解决方案

创建一个客户端组件,读取当前 URL 的路径名。通过替换路径中的当前语言段,生成所有其他支持语言的链接列表。点击时还会设置一个偏好 cookie,确保未来访问时记住用户的选择。

步骤

1. 定义语言配置

确保您的 i18n.config.ts 文件包含语言列表以及您将使用的 cookie 名称。

// i18n.config.ts

export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';

2. 创建语言切换器组件

创建一个新文件,例如 app/components/LanguageSwitcher.tsx。此组件必须是客户端组件,以便使用诸如 usePathname 之类的钩子。

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

import { usePathname } from 'next/navigation';
import Link from 'next/link';
import { locales, localeCookieName } from '@/i18n.config';

export default function LanguageSwitcher() {
  const pathname = usePathname();

  // 此函数设置 cookie
  const setLocaleCookie = (locale: string) => {
    document.cookie = `${localeCookieName}=${locale}; path=/; max-age=31536000; samesite=lax`;
  };

  // 此函数从路径中移除当前语言
  const getRedirectedPath = (locale: string) => {
    if (!pathname) return '/';
    const segments = pathname.split('/');
    segments[1] = locale; // 语言始终是第一个段
    return segments.join('/');
  };

  return (
    <div>
      {locales.map((locale) => (
        <Link
          key={locale}
          href={getRedirectedPath(locale)}
          onClick={() => setLocaleCookie(locale)}
          style={{
            display: 'inline-block',
            padding: '0.5rem',
            textDecoration: 'underline',
          }}
        >
          {locale.toUpperCase()}
        </Link>
      ))}
    </div>
  );
}

3. 将切换器添加到您的布局中

将新组件导入并放置到根布局文件 app/[lang]/layout.tsx 中。这将使其在所有页面上可见。

// app/[lang]/layout.tsx
import LanguageSwitcher from '@/app/components/LanguageSwitcher';

export async function generateStaticParams() {
  // 这告诉 Next.js 预渲染 'en'、'es' 和 'fr'
  return [{ lang: 'en' }, { lang: 'es' }, { lang: 'fr' }];
}

export default function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { lang: string };
}) {
  return (
    <html lang={params.lang}>
      <body>
        <header>
          {/* 将切换器添加到您的 header 或 nav 中 */}
          <LanguageSwitcher />
        </header>
        <main>{children}</main>
      </body>
    </html>
  );
}

现在,当用户在 /es/products/123 页面并点击“EN”时,组件会将新路径计算为 /en/products/123,并将 NEXT_LOCALE cookie 设置为 'en'。