Next.js15+next-intl默认Locale为az却强制跳/en前缀求助
解决Next.js 15 + next-intl默认Locale被强制跳转到/en的问题
问题根源
你的核心问题出在getLocale方法的Accept-Language匹配逻辑上:大多数现代浏览器默认的Accept-Language请求头会包含en(比如en-US,en;q=0.9),而你用startsWith(locale)判断时,en会被优先命中,导致页面强制跳转到/en路径;换成fr时,浏览器无对应语言头,就会 fallback 到默认的az。
同时还存在一个隐性问题:cookies.get("NEXT_LOCALE")返回的是Cookie对象,直接返回会导致语言匹配失败,需要取value属性。
解决方案
根据你的需求(默认打开无前缀的az站点),提供两种修改方案:
方案1:保留Accept-Language匹配,但优先默认Locale
这种方案会优先使用用户手动设置的语言(Cookie),其次优先匹配az,最后才根据浏览器语言匹配其他Locale:
// /src/middleware.js import createMiddleware from "next-intl/middleware"; // 解析Accept-Language头,提取主语言码(如en-US→en) function parseAcceptLanguage(acceptLanguage) { return acceptLanguage.split(',').map(item => { const [lang] = item.trim().split(';'); return lang.split('-')[0]; }); } const intlMiddleware = createMiddleware({ locales: ["az", "en", "ru"], defaultLocale: "az", localePrefix: "as-needed", async getLocale({ cookies, headers }) { // 优先读取用户手动设置的语言Cookie const cookieLocale = cookies.get("NEXT_LOCALE"); if (cookieLocale) { return cookieLocale.value; } const acceptLanguage = headers.get("accept-language"); if (acceptLanguage) { const preferredLangs = parseAcceptLanguage(acceptLanguage); // 优先匹配默认Locale az if (preferredLangs.includes('az')) { return 'az'; } // 再匹配其他支持的Locale for (const lang of preferredLangs) { if (["en", "ru"].includes(lang)) { return lang; } } } // 所有匹配失败,返回默认Locale return "az"; }, }); export const config = { matcher: ["/", "/((?!api|_next|.*\\..*).*)"] }; export default intlMiddleware;
方案2:完全忽略浏览器语言,强制默认打开az站点
如果你希望不管浏览器语言设置如何,默认都打开无前缀的az站点,仅通过Cookie切换语言,可以简化逻辑:
// /src/middleware.js import createMiddleware from "next-intl/middleware"; const intlMiddleware = createMiddleware({ locales: ["az", "en", "ru"], defaultLocale: "az", localePrefix: "as-needed", async getLocale({ cookies }) { // 仅读取用户手动设置的语言Cookie,否则返回默认Locale const cookieLocale = cookies.get("NEXT_LOCALE"); return cookieLocale?.value || "az"; }, }); export const config = { matcher: ["/", "/((?!api|_next|.*\\..*).*)"] }; export default intlMiddleware;
注意事项
- 不要在
next.config.mjs中添加Next.js原生的i18n配置,next-intl与原生i18n路由不能混用,会导致冲突错误。 - 保持
/app/i18n/routing.js的配置不变,确保与middleware中的Locale列表一致。
内容的提问来源于stack exchange,提问作者Farid Rashidov
相关产品推荐
相关产品推荐

