修改URL中locale时语言与NEXT_LOCALE未正常变更,求技术支持
解决URL修改locale后语言设置不生效的问题
核心问题分析
你的middleware里直接修改request.cookies是无效的——request对象是只读的,要设置cookie必须通过NextResponse对象操作并返回该响应,才能让浏览器生效。另外当前逻辑只修改了NEXT_LOCALE但未同步langkey cookie,且部分路径未返回响应,导致cookie设置无法生效。
修改后的middleware.ts代码
import { NextRequest, NextResponse } from 'next/server'; import { ModalKeys, Paths } from './src/types/paths'; export function middleware(request: NextRequest) { const accessToken = request.cookies.get('accessToken')?.value; const url = request.nextUrl; const hostname = request.headers.get('host'); const checkDomain = hostname?.includes('localhost') ? 'localhost' : hostname; process.env.HOST = checkDomain || ''; const locale = url.locale || 'en'; const currentLang = request.cookies.get('langkey')?.value; // 创建基础响应对象 let response = NextResponse.next(); // 同步locale与cookie if (locale !== currentLang) { response.cookies.set('NEXT_LOCALE', locale); response.cookies.set('langkey', locale); // 同步langkey,避免后续判断偏差 } // 登录状态校验逻辑 if ( accessToken && (url.hash === ModalKeys.LOGIN || url.hash === ModalKeys.REGISTER) ) { response = NextResponse.redirect(new URL(Paths.HOME, request.url)); // 重定向时同步cookie response.cookies.set('NEXT_LOCALE', locale); response.cookies.set('langkey', locale); return response; } if (!accessToken && url.pathname.startsWith('/profile/')) { response = NextResponse.redirect(new URL(`/${ModalKeys.LOGIN}`, request.url)); return response; } if (!accessToken && url.pathname.startsWith('/setting/')) { response = NextResponse.redirect(new URL(`/${ModalKeys.LOGIN}`, request.url)); return response; } // 所有路径返回响应,确保cookie生效 return response; } export const config = { matcher: ['/((?!api|_next|static|favicon.ico|public|assets).*)'] };
关键修改点说明
- 用NextResponse操作cookie:不再直接修改
request.cookies,而是创建NextResponse实例,通过它设置cookie后返回响应,保证浏览器能接收到更新后的cookie。 - 同步langkey与NEXT_LOCALE:因为逻辑中
currentLang从langkey读取,所以locale变化时需同步更新这两个cookie,避免后续判断出现不一致。 - 全路径返回响应:原代码在无需跳转的场景下未返回响应,导致cookie设置不生效,现在所有分支都返回对应响应对象。
额外检查项
- 确认页面组件通过
useRouter().locale获取当前语言,或在服务端函数(如getServerSideProps)中通过context.locale读取。 - 检查i18n资源文件的路径、命名是否符合Next.js的i18n规则,确保各locale对应的语言包能被正确加载。
内容的提问来源于stack exchange,提问作者Meylis Ovezov
相关产品推荐
相关产品推荐

