
本文旨在解决 next.js 13 国际化路由中常见的 'incorrect locale information provided' 错误。当浏览器发送 `['*']` 作为语言偏好时,next.js 的 i18n 模块可能无法正确识别。通过引入一个条件判断,将无效的 `['*']` 语言数组替换为预设的默认语言(如 'ar'),可以有效规避此问题,确保国际化路由正常工作。
Next.js 提供了强大的国际化 (i18n) 路由功能,允许开发者根据用户的语言偏好提供多语言内容。然而,在实际应用中,有时会遇到一个棘手的问题,即在遵循官方文档配置 i18n 路由后,系统抛出 "Incorrect locale information provided" 错误。这个错误通常发生在语言数组中包含一个特殊的通配符 *,而 Next.js 的 i18n 模块无法将其识别为有效的语言环境标识符。
在某些情况下,用户的浏览器可能会在 Accept-Language 请求头中发送 * 作为其语言偏好,或者在处理语言数组时,由于某种原因导致最终的语言数组变为 ['*']。根据 BCP 47 语言标签标准,* 并非一个有效的语言环境标识符。Next.js 的国际化路由机制依赖于标准的语言标签来匹配和解析路由。当它接收到一个包含 ['*'] 的语言数组时,由于无法将其映射到任何已定义的语言环境,便会抛出 "Incorrect locale information provided" 错误。
这个问题的核心在于,Next.js 期望接收到诸如 en、zh-CN、fr 等符合标准的语言代码。而 * 作为一个通配符,在语言环境识别的上下文中是无效的。
解决此问题的关键在于在 Next.js 处理语言数组之前,对其进行预处理。我们需要识别并替换掉无效的 ['*'] 语言数组,将其替换为一个我们预设的默认或回退语言。
以下是如何实现这一逻辑的示例代码:
// 假设这是你在 Next.js middleware.ts 或某个处理语言偏好的工具函数中
// 获取到用户语言偏好的逻辑
function getPreferredLocale(requestHeaders) {
// 从请求头或其他来源获取语言数组
// 例如,通过 next/server 的 `NextRequest` 对象获取 `Accept-Language`
let languages = ['en']; // 默认值,以防万一
// 实际应用中,这里会解析 requestHeaders['Accept-Language']
// 假设解析后得到一个数组,例如 ['en-US', 'en', '*'] 或 ['*']
// 模拟从请求头获取的语言数组
// For demonstration:
// const acceptLanguageHeader = requestHeaders.get('Accept-Language');
// if (acceptLanguageHeader) {
// languages = acceptLanguageHeader.split(',').map(lang => lang.split(';')[0].trim());
// }
// 核心解决方案:处理 ['*'] 的情况
if (languages.length === 1 && languages[0] === '*') {
// 当语言数组仅包含 '*' 时,将其替换为应用程序的默认语言
// 例如,替换为 'en' (英语) 或 'ar' (阿拉伯语,根据原始问题)
console.warn("Detected invalid locale preference ['*'], falling back to default locale.");
languages = ['en']; // 替换为你的应用默认语言,例如 'en', 'zh', 'ar' 等
}
// 接下来,你可以根据这个 languages 数组来决定最终的 locale
// 比如,与你应用支持的语言列表进行匹配
const supportedLocales = ['en', 'zh', 'ar']; // 你的应用支持的语言列表
const foundLocale = languages.find(lang => supportedLocales.includes(lang.split('-')[0])) || supportedLocales[0];
return foundLocale;
}
// 示例用法 (在 Next.js 的 middleware.ts 中)
// import { NextRequest, NextResponse } from 'next/server';
// export function middleware(request: NextRequest) {
// const preferredLocale = getPreferredLocale(request.headers);
// // 之后,你可以将 preferredLocale 用于重定向或设置请求头等
// // 例如:
// // const { pathname } = request.nextUrl;
// // if (!pathname.startsWith(`/${preferredLocale}/`) && pathname !== `/${preferredLocale}`) {
// // return NextResponse.redirect(new URL(`/${preferredLocale}${pathname}`, request.url));
// // }
// return NextResponse.next();
// }
// 假设我们直接有一个 languages 数组
let userLanguages = ['*'];
let effectiveLocale = getPreferredLocale({ /* mock headers if needed */ }); // 调用时传入模拟或实际的请求头
console.log("Effective locale after processing:", effectiveLocale); // 预期输出 'en'
userLanguages = ['en-US', 'en'];
effectiveLocale = getPreferredLocale({ /* mock headers if needed */ });
console.log("Effective locale for en-US, en:", effectiveLocale); // 预期输出 'en'
userLanguages = ['fr', 'en'];
effectiveLocale = getPreferredLocale({ /* mock headers if needed */ });
console.log("Effective locale for fr, en:", effectiveLocale); // 预期输出 'en' (因为 fr 不在 supportedLocales 中,所以回退到第一个)
代码解释:
通过上述方法,你可以有效地处理 Next.js 国际化路由中因 ['*'] 语言偏好而导致的 "Incorrect locale information provided" 错误,从而提高应用程序的鲁棒性和用户体验。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号