构建语言切换器
允许用户在任意页面切换语言
问题
用户在某个特定页面(如 /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 等 hooks。
// 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();
// This function sets the cookie
const setLocaleCookie = (locale: string) => {
document.cookie = `${localeCookieName}=${locale}; path=/; max-age=31536000; samesite=lax`;
};
// This function strips the current locale from the path
const getRedirectedPath = (locale: string) => {
if (!pathname) return '/';
const segments = pathname.split('/');
segments[1] = locale; // The locale is always the first segment
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() {
// This tells Next.js to pre-render 'en', 'es', and '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>
{/* Add the switcher to your header or nav */}
<LanguageSwitcher />
</header>
<main>{children}</main>
</body>
</html>
);
}
现在,当用户在 /es/products/123 页面点击“EN”时,组件会计算新路径为 /en/products/123,并将 NEXT_LOCALE cookie 设置为 'en'。