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

Gatsby动态页面数据获取疑难:getServerData与GraphQL变量传递

Gatsby + GraphQL 动态页面与数据查询解决方案

核心结论

  1. 通过gatsby-node.js的createPages创建的模板页面不支持getServerData,该API仅对src/pages目录下的页面生效(包括文件系统路由页面)。
  2. 文件系统路由的变量传递问题,可通过规范路由命名、匹配变量类型解决,同时该方案天然支持getServerData。

推荐解决方案:文件系统路由实现全需求

1. 创建动态路由页面

在src/pages目录下创建对应路由文件:

  • 单层级slug:[slug].js(如访问/shirt时,slug值为shirt)
  • 多级路径:[...slug].js(如访问/men/shirt时,slug为数组["men", "shirt"])

2. 传递slug到页面查询

对于[slug].js,Gatsby会自动将路由参数作为查询变量$slug传入,直接使用你的查询即可:

export const query = graphql`
  query CollectionPageQuery($slug: String) {    
    allCmsPlp(
      filter: { parameters: { collection: { seo: { slug: { eq: $slug } } } } }
    ) {
      edges {
        node {
          parameters {
            collection {
              seo { slug }
              brandId
              categoryId
              generic
              clusterId
            }
          }
          sections { name data }
        }
      }
    }
  }
`

若使用[...slug].js,需将变量类型改为[String],并调整过滤逻辑(比如用in替代eq)。

3. 集成getServerData

直接在页面组件中导出getServerData函数,从context.params获取slug并执行SSR查询:

export async function getServerData(context) {
  const { slug } = context.params;
  // 示例:调用外部API获取SSR数据
  const res = await fetch(`https://your-api.com/collection/${slug}`);
  const serverData = await res.json();

  return {
    props: { serverData }
  };
}

// 组件中同时使用页面查询数据和SSR数据
export default function CollectionPage({ data, serverData }) {
  const cmsData = data.allCmsPlp.edges[0]?.node;
  return (
    <div>
      <h1>{cmsData?.parameters?.collection?.seo?.slug}</h1>
      <div>{JSON.stringify(serverData)}</div>
    </div>
  );
}

备选方案:createPages静态生成(无getServerData支持)

若必须用createPages创建页面,只能实现静态生成/增量再生,无法使用getServerData:

1. 在gatsby-node.js中传递context

exports.createPages = async ({ graphql, actions }) => {
  const { createPage } = actions;
  // 查询所有需要生成页面的slug
  const { data } = await graphql(`
    query {
      allCmsPlp {
        edges {
          node {
            parameters {
              collection { seo { slug } }
            }
          }
        }
      }
    }
  `);

  // 遍历生成页面
  data.allCmsPlp.edges.forEach(edge => {
    const slug = edge.node.parameters.collection.seo.slug;
    createPage({
      path: `/collections/${slug}`,
      component: require.resolve("./src/templates/collection.js"),
      context: { slug } // 将slug传入模板查询
    });
  });
};

2. 模板页面中接收变量

模板查询与之前一致,变量$slug会自动从context中获取。


问题排查指南

  1. 文件系统路由查询变量不存在:
    • 确认页面文件在src/pages目录下,命名格式正确(如[slug].js)
    • 访问路径需包含有效slug(如/your-collection)
    • 检查变量类型与路由匹配(单层级用String,多层级用[String])
  2. getServerData不生效:
    • 仅src/pages下的页面支持该API,模板页面(src/templates)不兼容
    • 修改getServerData后需重启Gatsby开发服务

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:52:56