如何在Next.js客户端组件用next-intl实现无刷新切换语言
在Next.js客户端组件中用next-intl实现无刷新切换语言(无需i18n路由)
核心思路
服务端可通过unstable_setRequestLocale从Cookie读取locale,但客户端组件需手动处理Cookie修改+locale状态同步,以此实现无刷新切换。
实现步骤
1. 配置next-intl从Cookie获取locale
在middleware.ts中配置next-intl的locale来源为Cookie,确保服务端和客户端初始locale一致:
import createMiddleware from 'next-intl/middleware'; export default createMiddleware({ locales: ['zh-CN', 'en'], defaultLocale: 'zh-CN', localeDetection: false, // 优先从Cookie读取locale getLocale(request) { return request.cookies.get('NEXT_LOCALE')?.value || 'zh-CN'; } }); export const config = { matcher: ['/((?!api|_next|.*\\..*).*)'] };
2. 封装客户端语言切换Hook
创建自定义HookuseClientLocale,封装Cookie修改和状态同步逻辑,方便组件复用:
'use client'; import { useState, useEffect } from 'react'; import { useLocale } from 'next-intl'; import { getCookie, setCookie } from 'cookies-next'; export function useClientLocale() { const initialLocale = useLocale(); const [locale, setLocale] = useState(initialLocale); // 修改Cookie并更新本地状态 const changeLocale = (newLocale: string) => { setCookie('NEXT_LOCALE', newLocale, { path: '/', maxAge: 365 * 24 * 60 * 60 // 1年有效期 }); setLocale(newLocale); }; // 页面刷新时同步Cookie中的locale useEffect(() => { const cookieLocale = getCookie('NEXT_LOCALE') as string; if (cookieLocale && cookieLocale !== locale) { setLocale(cookieLocale); } }, []); return { locale, changeLocale }; }
3. 在客户端组件中使用
在登录页面(或其他客户端组件)中引入Hook,实现语言切换按钮:
'use client'; import { useMessages } from 'next-intl'; import { useClientLocale } from '@/hooks/useClientLocale'; export default function LoginPage() { const { locale, changeLocale } = useClientLocale(); const messages = useMessages(); return ( <div className="login-container"> {/* 语言切换按钮 */} <div className="locale-switcher"> <button onClick={() => changeLocale('zh-CN')}>中文</button> <button onClick={() => changeLocale('en')}>English</button> </div> {/* 登录表单内容,使用messages渲染多语言文本 */} <h1>{messages.login.title}</h1> <input placeholder={messages.login.usernamePlaceholder} /> <input placeholder={messages.login.passwordPlaceholder} type="password" /> <button>{messages.login.submitBtn}</button> </div> ); }
关键说明
- 直接操作
NEXT_LOCALECookie(next-intl默认使用的Cookie名称),确保服务端能正确读取最新locale - 通过React状态
locale触发组件重渲染,实现无刷新更新多语言内容 - 自定义Hook封装逻辑后,可在任意客户端组件中复用切换功能
内容的提问来源于stack exchange,提问作者lik3yoo
相关产品推荐
相关产品推荐

