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)两种语言版本,用于演示本地化能力。
示例站点的数据流向可以概括为:
- 构建期
gatsby-source-contentful通过 Contentful Content Delivery API 拉取 Space 中的 entry(条目)与 asset(资源); - 插件将数据转换为 Gatsby GraphQL 数据层中的
ContentfulProduct、ContentfulCategory、ContentfulAsset等节点类型; - 页面组件通过 GraphQL 查询这些节点,并调用
gatsby-plugin-image处理图片; - 构建产出静态 HTML,部署后即可访问。
环境准备与本地运行
示例的依赖与脚本定义在 package.json 中,核心依赖包括:
gatsby(主框架)gatsby-source-contentful(Contentful 数据源插件,这是本示例的主角)gatsby-plugin-image与gatsby-plugin-sharp(图片处理)gatsby-transformer-remark(将 Contentful 中的 Markdown 富文本字段转换为可渲染 HTML)gatsby-plugin-typography、typography(排版样式)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 |
accessToken | Content Delivery API 的访问令牌 | 生产环境应通过环境变量注入,避免将密钥写死在配置中提交到仓库 |
此外该插件还支持host、environment(环境,默认 master)、downloadLocal、typePrefix等更多选项;生产项目建议至少将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) } } } } }这段查询有两个值得注意的细节:
- 别名(alias):同一页面内用
us和german两个别名并发查询同一类型,分别筛出英文与德文产品,实现双语列表同屏展示; 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: 18px、scaleRatio: 2.15,并在平板/移动端媒体查询中调整字号),由gatsby-plugin-typography的pathToConfigModule选项引入。
小结:从示例到生产落地
对照本示例,把 Gatsby 接到自有 Contentful Space 只需四步:
- 在
gatsby-config.js中配置gatsby-source-contentful,填入自己的spaceId与accessToken(生产用环境变量); - 定义内容模型后,在页面中通过
allContentfulXxx/contentfulXxx查询节点,结合node_locale处理多语言; - 用
{ContentfulXxx.id}.js文件路由加gatsbyPath生成动态详情页; - 对
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),仅供参考