Gatsby 对接 Contentful CMS:基于 gatsby-source-contentful 构建数据驱动站点实战指南
2026/9/20 12:10:24 网站建设 项目流程

Gatsby 对接 Contentful CMS:基于 gatsby-source-contentful 构建数据驱动站点实战指南

【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby

本文以仓库中的 using-contentful 示例站点 为蓝本,讲解如何让 Gatsby 从 Contentful CMS API 拉取内容并构建静态站点。读完本文,你将掌握gatsby-source-contentful的完整配置方法、多语言(本地化)内容查询、基于文件路由的内容型动态页面,以及 Contentful 图片资源在 Gatsby 中的三种布局与四种占位符用法,可直接照搬搭建自己的 CMS 驱动站点。

示例站点一览

仓库中的examples/using-contentful是一个演示 "如何构建从 Contentful CMS API 拉取数据的 Gatsby 站点" 的完整示例。示例使用了一个公开的 Contentful 示例 Space(空间),内含**产品(Product)分类(Category)**两类内容模型,并预先为这些内容配置了英语(en-US)和德语(de)两种语言版本,用于演示本地化能力。

示例站点的数据流向可以概括为:

  1. 构建期gatsby-source-contentful通过 Contentful Content Delivery API 拉取 Space 中的 entry(条目)与 asset(资源);
  2. 插件将数据转换为 Gatsby GraphQL 数据层中的ContentfulProductContentfulCategoryContentfulAsset等节点类型;
  3. 页面组件通过 GraphQL 查询这些节点,并调用gatsby-plugin-image处理图片;
  4. 构建产出静态 HTML,部署后即可访问。

环境准备与本地运行

示例的依赖与脚本定义在 package.json 中,核心依赖包括:

  • gatsby(主框架)
  • gatsby-source-contentful(Contentful 数据源插件,这是本示例的主角)
  • gatsby-plugin-imagegatsby-plugin-sharp(图片处理)
  • gatsby-transformer-remark(将 Contentful 中的 Markdown 富文本字段转换为可渲染 HTML)
  • gatsby-plugin-typographytypography(排版样式)
  • react/react-dom

在示例目录下安装依赖后即可启动:

npm install npm run develop # 启动开发服务器 npm run build # 生产构建,输出静态文件 npm run serve # 本地预览构建产物 npm run clean # 清理缓存(.cache 与 public)

构建时插件会实时请求 Contentful API,网络可达即可拉取到示例 Space 的全部内容并生成页面。

插件配置:gatsby-source-contentful 的核心参数

示例的完整配置见 gatsby-config.js:

module.exports = { siteMetadata: { title: `Gatsby with Contentful`, }, plugins: [ `gatsby-plugin-image`, { resolve: `gatsby-source-contentful`, options: { spaceId: `rocybtov1ozk`, accessToken: `6f35edf0db39085e9b9c19bd92943e4519c77e72c852d961968665f1324bfc94`, }, }, `gatsby-transformer-remark`, { resolve: `gatsby-plugin-typography`, options: { pathToConfigModule: `src/utils/typography`, }, }, ], }

其中最关键的是gatsby-source-contentful的两个必填参数:

参数作用说明
spaceId指定要拉取的 Contentful Space每个 Space 对应一套内容模型与内容数据,示例使用的是公开演示 Space
accessTokenContent Delivery API 的访问令牌生产环境应通过环境变量注入,避免将密钥写死在配置中提交到仓库

此外该插件还支持hostenvironment(环境,默认 master)、downloadLocaltypePrefix等更多选项;生产项目建议至少将accessToken替换为环境变量引用(如process.env.CONTENTFUL_ACCESS_TOKEN)。

配置完成后,插件会在构建期创建以下三类核心节点,供 GraphQL 查询:

  • ContentfulProduct:对应内容模型 "Product" 的 entry,含产品名、描述、价格、图片、品牌、分类等字段;
  • ContentfulCategory:对应内容模型 "Category" 的 entry;
  • ContentfulAsset:Space 中的媒体资源(图片)。

由于示例使用了gatsby-transformer-remark,Product 的productDescription字段还会产生childMarkdownRemark子节点,从而可以在页面上通过dangerouslySetInnerHTML直接渲染 Markdown 解析后的 HTML。

用 GraphQL 拉取 Contentful 内容:首页产品列表

首页 src/pages/index.js 演示了最基本的查询方式——通过allContentfulProduct获取全部产品节点:

query { us: allContentfulProduct(filter: { node_locale: { eq: "en-US" } }) { edges { node { id gatsbyPath(filePath: "/products/{ContentfulProduct.id}") productName { productName } image { gatsbyImageData(layout: FIXED, width: 75) } } } } }

这段查询有两个值得注意的细节:

  1. 别名(alias):同一页面内用usgerman两个别名并发查询同一类型,分别筛出英文与德文产品,实现双语列表同屏展示;
  2. gatsbyPath:这是gatsby-source-contentful提供的便捷字段,通过传入文件路由的filePath模板,即可直接拿到该节点对应页面的真实路径,无需手动拼接 URL,页面内用它做<Link to={node.gatsbyPath}>跳转。

本地化(Localization):node_locale 与逐语言建节点

首页明确展示了插件对 Contentful 本地化特性的完整支持。Contentful 允许同一 entry 拥有多语言版本,示例 Space 中的产品同时包含英文和德文内容。插件对本地化的处理规则是:

  • 每个语言版本分别创建独立的 entry 与 asset 节点(缺失的翻译按 fallback 规则回退);
  • 每个节点额外增加node_locale字段,标识该节点所属语言;
  • 因此可以通过filter: { node_locale: { eq: "en-US" } }eq: "de"精确筛选单一语言的数据集。

页面渲染部分据此把产品列表分成 "en-US" 与 "de" 两个区块展示:

const usProductEdges = this.props.data.us.edges const deProductEdges = this.props.data.german.edges // ...分别渲染 <h3>en-US</h3> 与 <h3>de</h3> 两组产品

这一机制让 "一 Space 多语言、站点按语言分流" 成为开箱即用的能力。

文件路由动态页面:{ContentfulProduct.id} 与 gatsbyPath

示例没有使用传统的createPagesAPI,而是采用了 Gatsby 的**文件路由(File System Route API)**约定。两个动态页面模板位于:

  • src/pages/products/{ContentfulProduct.id}.js:为每个产品生成/products/<id>页面;
  • src/pages/categories/{ContentfulCategory.id}.js:为每个分类生成/categories/<id>页面。

以产品页为例,Gatsby 会自动将文件路由中的{ContentfulProduct.id}解析为查询参数$id,模板通过contentfulProduct(id: { eq: $id })精确查询单个产品:

query($id: String!) { contentfulProduct(id: { eq: $id }) { productName { productName } productDescription { childMarkdownRemark { html } } price image { gatsbyImageData(width: 200) } brand { companyName { companyName } } categories { id gatsbyPath(filePath: "/categories/{ContentfulCategory.id}") title { title } } } }

页面渲染时解构出产品名称、价格、图片,用dangerouslySetInnerHTML渲染 Markdown 描述,并通过分类节点的gatsbyPath生成 "查看其他分类" 的链接。分类页模板与之对称:查询contentfulCategory(id: { eq: $id }),展示分类图标与关联产品列表,产品链接同样由gatsbyPath(filePath: "/products/{ContentfulProduct.id}")提供。

这种 "文件路由 + gatsbyPath" 的组合,把"内容节点 → 页面路径"的映射完全交给框架处理,代码更简洁,也避免手写 slug 逻辑出错。

图片处理:Contentful Image API 与 gatsby-plugin-image 集成

示例站点专门用 src/pages/image-api.js 一页演示图片能力。Contentful 中的图片资源经插件进入ContentfulAsset节点后,可直接通过gatsbyImageData字段调用gatsby-plugin-image的图片优化管线,配合<GatsbyImage>组件渲染。

页面在单个查询中同时请求多种处理形态:

query { allContentfulAsset(filter: { node_locale: { eq: "en-US" } }) { edges { node { title id constrained: gatsbyImageData(layout: CONSTRAINED, width: 186) fixed: gatsbyImageData(layout: FIXED, width: 100, height: 100) fullWidth: gatsbyImageData(layout: FULL_WIDTH) dominant: gatsbyImageData( layout: CONSTRAINED placeholder: DOMINANT_COLOR width: 186 ) blurred: gatsbyImageData( layout: CONSTRAINED placeholder: BLURRED width: 186 ) traced: gatsbyImageData( layout: CONSTRAINED placeholder: TRACED_SVG width: 186 ) } } } }

三种布局(layout)

布局行为适用场景
CONSTRAINED(默认)以源图尺寸或传入的width/height为上限展示,容器更小时按比例缩放,并生成多档缩小版本供移动端按需加载常规内容图、网格图
FIXED固定尺寸,不随容器收缩,尺寸由源图或width/height决定头像、图标等尺寸确定的场景
FULL_WIDTH始终撑满容器宽度,不受最大尺寸限制,按屏幕断点生成多档图源,适合 banner、hero 图全宽横幅、首屏大图;可传breakpoints自定义断点

四种占位符(placeholder)

占位符原理适用场景
DOMINANT_COLOR计算源图主色,用纯色背景占位轻量、加载极快
BLURRED生成极低分辨率模糊图作为背景占位默认推荐,兼顾美观与性能
TRACED_SVG生成简化扁平 SVG 占位简单图形、含透明通道的图片
NONE不生成占位无需占位效果时

示例页面把上述 6 种形态的图片逐一以<GatsbyImage image={...} alt={title} />渲染,并分别给出对应的 GraphQL 查询片段,是查阅参数组合用法最直接的参照(image-api.js)。

布局与排版:整体页面的组织方式

  • src/layouts/index.js 定义了全站通用布局:顶部为标题栏(链接回首页),主体内容限定maxWidth: 650,底部注明数据来源。各页面通过<Layout>包裹内容复用该结构。
  • src/utils/typography.js 基于typography库自定义了排版主题(baseFontSize: 18pxscaleRatio: 2.15,并在平板/移动端媒体查询中调整字号),由gatsby-plugin-typographypathToConfigModule选项引入。

小结:从示例到生产落地

对照本示例,把 Gatsby 接到自有 Contentful Space 只需四步:

  1. gatsby-config.js中配置gatsby-source-contentful,填入自己的spaceIdaccessToken(生产用环境变量);
  2. 定义内容模型后,在页面中通过allContentfulXxx/contentfulXxx查询节点,结合node_locale处理多语言;
  3. {ContentfulXxx.id}.js文件路由加gatsbyPath生成动态详情页;
  4. ContentfulAsset节点使用gatsbyImageData输出经优化的响应式图片。

仓库中与本主题相关的深度资料还包括:gatsby-source-contentful 插件源码(可查看节点创建与本地化实现的完整逻辑)、gatsby-plugin-image 文档,以及 source-contentful 基准示例。若需复制此示例离线体验,可git clone当前仓库后在 examples/using-contentful 目录下运行npm install && npm run develop

【免费下载链接】gatsbyReact-based framework with performance, scalability, and security built in.项目地址: https://gitcode.com/gh_mirrors/ga/gatsby

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询