You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 10:05:24