Next.js 13 App Router中generateMetadata中文路径编码异常问题
Next.js App Router generateMetadata 中文路径自动编码问题解决
问题分析
你遇到的是Next.js App Router中generateMetadata自动编码alternates路径的问题:当你传入含中文的路径字符串时,Next.js会自动调用encodeURI对路径进行编码,导致最终生成的<link>标签href显示为编码后的/zh/%E5%B7%B4%E5%9F%BA%E6%96%AF%E5%9D%A6,而非期望的/zh/巴基斯坦。直接用decodeURI无效的原因是,解码后的字符串会被Next.js重新编码。
解决方案
核心思路是避免让Next.js自动处理路径编码,通过传入URL对象替代字符串路径,让Next.js直接使用你定义的未编码路径。另外需要确保原始的国家名称是未编码的中文字符(如果接口返回的是编码后的字符串,需先解码)。
修改后的代码
export async function generateMetadata({ params }) { const { data } = await getData(params); const languagePaths = {}; const baseUrl = 'https://www.grumpeat.com'; data?.countries?.data?.grumpeatCountries?.content?.forEach((country) => { country?.availableLanguages?.forEach((countryLanguage) => { const language = `${countryLanguage.languageCode}-${country.code}`; // 若接口返回的countryName是编码后的字符串,先解码 const decodedCountryName = decodeURIComponent(countryLanguage.countryName); const countryPath = decodedCountryName?.replace(/%20|\s/g, '_'); // 构造URL对象,传入未编码路径 const alternateUrl = new URL(`/${countryLanguage.languageCode}/${countryPath}`, baseUrl); languagePaths[language] = alternateUrl; }); }); return { metadataBase: new URL(baseUrl), alternates: { canonical: '/', languages: languagePaths, } } }
关键改动说明
- 替换
map为forEach:遍历操作不需要返回新数组,forEach更符合语义 - 增加解码步骤(可选):如果接口返回的
countryName是URL编码后的字符串,用decodeURIComponent解码为中文 - 使用
URL对象构造路径:Next.js会直接使用URL对象的href属性,不会再自动编码路径,确保最终生成的<link>标签href显示为未编码的中文路径
内容的提问来源于stack exchange,提问作者Muhammad Naeem
相关产品推荐
相关产品推荐

