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

如何在Gatsby中创建带ID参数的动态路由

嘿,很高兴你已经把Gatsby项目顺利跑起来了!关于带ID参数的动态路由(类似React Router里的/path/:id),Gatsby有两种常用的实现方式,我给你一步步讲清楚:

方式一:文件系统路由API(推荐,Gatsby v2.20+支持)

这是最简单的实现方式,不需要修改配置文件,直接通过命名规则创建页面即可:

  • 在src/pages目录下创建带方括号的文件,比如你要做/post/:id的路由,就新建src/pages/post/[id].js。这里的[id]就是动态参数的占位符,对应URL里的具体ID值(比如/post/123里的123)。
  • 在这个组件里,用Gatsby内置的useParams()钩子(来自@reach/router)获取ID参数:
import { useParams } from "@reach/router";

export default function PostPage() {
  // 解构出动态参数id
  const { id } = useParams();

  return (
    <div className="post-page">
      <h1>文章ID:{id}</h1>
      {/* 这里可以根据id做后续操作,比如请求数据、渲染对应内容 */}
    </div>
  );
}
  • 如果需要多参数路由(比如/post/:category/:id),只要创建src/pages/post/[category]/[id].js,然后用const { category, id } = useParams()就能拿到两个参数。

方式二:通过gatsby-node.js创建动态页面(适合批量生成场景)

如果你的动态页面需要从数据源(比如CMS、本地Markdown文件、数据库)批量生成,就适合用这种方式:

  1. 在项目根目录的gatsby-node.js文件中,使用Gatsby的createPages API:
exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;

  // 第一步:查询所有需要生成页面的数据(这里以Markdown文章为例)
  const queryResult = await graphql(`
    query GetAllPosts {
      allMarkdownRemark {
        nodes {
          id
          frontmatter {
            slug
          }
        }
      }
    }
  `);

  // 第二步:遍历数据,为每一条数据创建动态页面
  queryResult.data.allMarkdownRemark.nodes.forEach(post => {
    createPage({
      // 页面的URL路径,这里用文章id作为动态部分
      path: `/post/${post.id}`,
      // 页面使用的模板组件路径
      component: require.resolve("./src/templates/post-template.js"),
      // 传递给模板的上下文参数,模板里可以通过pageContext获取
      context: {
        id: post.id,
      },
    });
  });
};
  1. 创建模板组件src/templates/post-template.js,在里面获取ID并渲染内容:
import { graphql } from "gatsby";

export default function PostTemplate({ data, pageContext }) {
  // 方式1:直接从pageContext拿id
  const postId = pageContext.id;
  // 方式2:通过GraphQL查询获取对应文章的详细数据
  const postContent = data.markdownRemark;

  return (
    <div>
      <h1>{postContent.frontmatter.title}</h1>
      <p>当前文章ID:{postId}</p>
      <div dangerouslySetInnerHTML={{ __html: postContent.html }} />
    </div>
  );
}

// 用context里的id作为查询变量,精准获取对应文章的数据
export const postQuery = graphql`
  query PostById($id: String!) {
    markdownRemark(id: { eq: $id }) {
      frontmatter {
        title
      }
      html
    }
  }
`;

小提示

  • 如果只是单个动态页面需求,优先用文件系统路由API,简单高效;
  • 如果需要批量生成页面(比如博客的每篇文章),就选gatsby-node.js的方式,灵活性更强。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:27:24