Next.js 捕获所有动态路由失效问题排查
问题根源:Catch-All路由的
slug参数格式错误 你遇到的问题核心在于getStaticPaths中返回的slug参数格式不符合Next.js Catch-All动态路由的要求。
为什么嵌套路由会404?
Next.js的[...slug].tsx这种Catch-All路由,期望params.slug是一个路径段数组,而不是包含完整路径字符串的单元素数组:
- 对于
/docs/ABCD,正确的params.slug是["ABCD"] - 对于
/docs/ABCD/1234,正确的params.slug是["ABCD", "1234"]
而你当前的代码中,把完整的路径字符串(比如"ABCD/1234")作为单个元素放到数组里,返回了{ params: { slug: ["ABCD/1234"] } },这会让Next.js认为你要匹配的是/docs/ABCD%2F1234(转义后的斜杠),自然找不到对应的路由,返回404。
修复方案:拆分路径字符串为数组
修改getStaticPaths中生成paths的逻辑,把提取到的slug字符串按/拆分成数组:
export const getStaticPaths = async () => { const DOCS_DIR = path.join(process.cwd() + '/src', 'docs') const docPaths = await glob(path.join(DOCS_DIR, '**/*.md')) const paths = docPaths.map((docPath) => { const slug = docPath.split('docs/')[1].replace('.md', '') // 将完整路径拆分为路径段数组 const slugSegments = slug.split('/') return { params: { slug: slugSegments } } }) return { paths, fallback: false } }
验证修改效果
- 对于
docs/ABCD.md,拆分后slugSegments是["ABCD"],对应路由/docs/ABCD,正常匹配 - 对于
docs/ABCD/1234.md,拆分后slugSegments是["ABCD", "1234"],对应路由/docs/ABCD/1234,可以正确匹配
另外,你的Link组件写法是正确的,href={'/docs/' + doc.slug}会被Next.js正确解析为对应的Catch-All路由参数,不需要调整。
为什么手动创建嵌套路由可行?
你手动创建的[EFGH]/1234.tsx属于嵌套动态路由,它的参数逻辑和Catch-All路由不同,Next.js会直接匹配/docs/EFGH/1234这个路径,所以能正常访问,但这显然不是你想要的可扩展方案,修复Catch-All路由的参数格式才是正确的解决方式。
内容的提问来源于stack exchange,提问作者husky
相关产品推荐
相关产品推荐

