Next.js i18n中间件重定向异常问题求助
Next.js本地化默认语言URL隐藏的循环重定向修复方案
问题核心是:用户主动切换到默认语言时,重定向到根路径后,中间件又根据请求头的语言偏好再次重定向到非默认语言,形成循环。解决方案是通过用户偏好Cookie记录用户主动选择的语言,让中间件优先使用Cookie值而非请求头。
步骤1:修改语言选择器,添加Cookie设置
当用户通过语言选择器切换语言时,将选择的语言代码存入Cookie,确保中间件能识别用户的主动选择:
// 语言选择器组件示例 export function LanguageSelector() { const fallbackLng = 'en'; // 与你的默认语言保持一致 const handleLanguageChange = (lng: string) => { // 设置Cookie,有效期30天,全站有效 document.cookie = `user-preferred-locale=${lng}; path=/; max-age=${30 * 24 * 60 * 60}; SameSite=Lax`; // 默认语言跳根路径,其他语言带前缀 window.location.href = lng === fallbackLng ? '/' : `/${lng}`; }; return ( <div> <button onClick={() => handleLanguageChange('en')}>English</button> <button onClick={() => handleLanguageChange('es')}>Español</button> </div> ); }
步骤2:修改中间件逻辑,优先读取Cookie
调整中间件,优先从Cookie获取用户偏好语言,只有当Cookie不存在时才使用请求头的Accept-Language:
export function middleware(req: NextRequest) { const pathname = req.nextUrl.pathname; const splitPath = pathname.split('/'); const currentLng = splitPath[1]; const fallbackLng = 'en'; // 你的默认语言 const languages = ['en', 'es']; // 支持的语言列表 // 优先从Cookie读取用户主动选择的语言,无Cookie时用请求头 const userPreferredLng = req.cookies.get('user-preferred-locale')?.value; const lng = userPreferredLng || getBestLocale(req.headers.get('Accept-Language')); // 默认语言路径重定向到根路径 if (currentLng === fallbackLng) { const newPath = `/${splitPath.slice(2).join('/')}`; return NextResponse.redirect(new URL(newPath, req.url)); } const pathnameIsMissingValidLocale = !languages.some((loc) => { return pathname.startsWith(`/${loc}/`) || pathname === `/${loc}`; }) && !pathname.startsWith('/_next'); // 无有效语言路径时,根据用户偏好处理 if (pathnameIsMissingValidLocale) { if (lng !== fallbackLng) { return NextResponse.redirect(new URL(`/${lng}${pathname}`, req.url)); } else { return NextResponse.rewrite( new URL(`/${fallbackLng}${pathname}`, req.url) ); } } return NextResponse.next(); }
修复原理
- 用户主动切换语言时,Cookie会记录其选择,中间件优先遵循该选择,不再依赖请求头的
Accept-Language。 - 当用户切换到默认语言(如
/en),会被重定向到根路径,但Cookie已设为en,后续访问根路径时,中间件读取Cookie值,直接重写为默认语言的内容,不会再跳转到请求头对应的语言。 - 若用户清除Cookie,会自动 fallback 到请求头语言,不影响首次访问的默认逻辑。
内容的提问来源于stack exchange,提问作者ChrisGM
相关产品推荐
相关产品推荐

