Next.js中getStaticPaths处理含/路径时encodeURIComponent失效404问题
这个问题的根因是Next.js生产环境的路径解析规则差异:生产构建完成后,Next.js会自动将URL中编码后的斜杠%2F解码为普通斜杠/,你当前使用的单级动态路由[foodTitle]仅能匹配路径中的单个片段,解码后多出的斜杠会被识别为路径分隔符,最终触发404。本地开发环境没有引入该自动解码逻辑,因此访问正常。
方案1:改用Catch-all动态路由(推荐,兼容性最好)
无需修改业务核心逻辑,仅调整路由结构和参数解析规则即可:
- 将
src/pages/food/[foodTitle].tsx重命名为src/pages/food/[...foodTitle].tsx - 修改
getStaticPaths逻辑,按数组格式传递动态参数:
export const getStaticPaths: GetStaticPaths = () => { const paths = foods.map((food) => ({ params: { // 把编码后的标题作为catch-all参数的唯一数组元素 foodTitle: [encodeURIComponent(food.title)] } })) return { paths, fallback: false } }
- 修改
getStaticProps的参数解析逻辑:
export const getStaticProps: GetStaticProps<Props, Params> = (ctx) => { const encodedTitle = ctx.params?.foodTitle[0] as string const title = decodeURIComponent(encodedTitle) const food = foods.find((food) => food.title === title) as Food return { props: { food } } }
- 首页Link组件的编码逻辑无需修改,可直接复用原有代码。
方案2:替换特殊字符(无需修改路由结构,简单快捷)
选择一个标题中不会出现的特殊字符(比如~、|等)作为斜杠的替代符,链路全程替换处理即可:
- 首页Link生成路径时替换斜杠:
<Link href={`/food/${food.title.replace(/\//g, '~')}`}> {food.title} </Link>
getStaticPaths生成路径时使用相同替换规则:
const paths = foods.map((food) => `/food/${food.title.replace(/\//g, '~')}`)
getStaticProps获取参数后反向替换回原斜杠:
const title = (ctx.params?.foodTitle as string).replace(/~/g, '/')
方案3:关闭Next.js自动路径解码(实验性配置,慎用)
如果不想改动业务代码,可以在next.config.js中添加配置关闭默认解码逻辑:
/** @type {import('next').NextConfig} */ const nextConfig = { experimental: { decodeURI: false } } module.exports = nextConfig
注意该配置属于实验性功能,可能会影响其他路由的正常解析,生产环境使用前需要做充分测试。
内容的提问来源于stack exchange,提问作者Saad
相关产品推荐
相关产品推荐

