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

使用File System Route API创建页面时Gatsby静态HTML构建报错

问题根因

你遇到的问题本质是Gatsby的文件系统路由(FileSystem Route API)默认会把所有MDX节点匹配到所有符合命名规则的{mdx.slug}.js模板上。gatsby develop是按需渲染,你没有访问错误生成的路径就不会触发报错,而gatsby build是全量生成所有匹配到的页面,当博客MDX被错误匹配到服务页模板渲染时,如果模板依赖的字段博客MDX不存在,就会抛出静态HTML构建失败的错误。


解决方案

方案1:修改路由模板文件名,增加匹配过滤(最便捷)

Gatsby 4及以上版本的文件系统路由支持在路由参数中添加过滤规则,直接限定每个模板匹配的MDX来源:

  • 把pages/blog/{mdx.slug}.js重命名为pages/blog/{mdx(sourceInstanceName: {eq: "blog"}).slug}.js
  • 把pages/services/{mdx.slug}.js重命名为pages/services/{mdx(sourceInstanceName: {eq: "services"}).slug}.js
    修改后每个模板只会匹配对应sourceInstanceName的MDX节点,不会再出现交叉匹配的问题。

方案2:改用gatsby-node.js手动生成页面(可控性最高)

如果不想修改文件名,可以放弃自动路由,通过gatsby-node.js的createPagesAPI手动生成页面,完全控制每个MDX对应的模板和路径:

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions
  // 查询所有MDX节点信息
  const result = await graphql(`
    query {
      allMdx {
        nodes {
          id
          slug
          sourceInstanceName
        }
      }
    }
  `)
  // 遍历生成对应页面
  result.data.allMdx.nodes.forEach(node => {
    if (node.sourceInstanceName === 'blog') {
      createPage({
        path: `/blog/${node.slug}/`,
        component: require.resolve('./src/pages/blog/{mdx.slug}.js'),
        context: { id: node.id }
      })
    }
    if (node.sourceInstanceName === 'services') {
      createPage({
        path: `/services/${node.slug}/`,
        component: require.resolve('./src/pages/services/{mdx.slug}.js'),
        context: { id: node.id }
      })
    }
  })
}

添加完上述代码后,删除原来的自动路由模板或者把模板移到src/templates目录下避免重复生成即可。

临时排查方案

如果需要先确认是不是交叉匹配导致的问题,可以在构建命令后加--verbose参数运行gatsby build --verbose,查看每个页面对应的生成模板,确认错误路径/services/blog-post-1/是否确实是调用了服务页模板生成。


内容的提问来源于stack exchange,提问作者Sam Quayle

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 13:45:00