如何在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文件、数据库)批量生成,就适合用这种方式:
- 在项目根目录的
gatsby-node.js文件中,使用Gatsby的createPagesAPI:
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, }, }); }); };
- 创建模板组件
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
相关产品推荐
相关产品推荐

