Claude Code 与 Contentful CMS 集成实践指南
用Claude Code集成Contentful CMS,覆盖API、类型、预览、locale、Next.js、Astro与ISR常见坑。
先把Contentful的边界说清楚
Contentful 是无头 CMS,也就是编辑后台和前端展示分离的内容管理系统。编辑在 Contentful 里维护文章、图片、作者、FAQ 和 CTA,前端通过 API 把这些内容渲染到 Next.js、Astro 或其他应用里。Claude Code 在这个场景里很有价值,但它不应该只被当成“帮我写一个 fetch”的工具。
真正容易出错的地方,是 Delivery API、Preview API、Management API、locale、环境变量、静态生成和缓存失效混在一起。很多项目一开始只验证了一篇英文已发布文章,到了中文草稿预览、图片发布、Webhook 重新生成页面时才发现问题。把这些边界先写进提示词,Claude Code 才能稳定地产生可审查的差异。
如果你还在整理博客 CMS 的整体结构,可以先看 Claude Code 博客 CMS。如果 CMS 内容还要提供给产品 API,可以参考 Claude Code API 开发。内容如何转成注册、购买和咨询线索,则可以继续看 内容漏斗审计。
区分三个API,不要共用token
Contentful 的 Content Delivery API 只读取已发布内容,Content Preview API 读取草稿和未发布修改,Content Management API 用来创建 content type、更新 entry、发布内容。Claude Code 的提示词和代码里都要明确这个分工。
| API | 用途 | token | 推荐位置 |
|---|---|---|---|
| Content Delivery API | 读取已发布文章和资源 | Delivery token | SSG、ISR、Server Component、Astro build |
| Content Preview API | 读取草稿和未发布修改 | Preview token | 仅限预览路由和服务端处理 |
| Content Management API | 创建模型、更新entry、publish | Management token或PAT | 本地脚本、可信CI任务 |
| Images API | 生成缩略图、转换格式 | 随Delivery/Preview上下文 | 图片helper、OGP、列表页 |
官方 JavaScript SDK 文档说明,Preview API 要同时使用 preview access token 和 host: "preview.contentful.com"。Contentful 也提醒 Personal Access Token 与用户权限绑定,应当像密码一样保护。实现前可以把这些官方资料放进任务说明:Contentful JavaScript SDK、Personal Access Tokens、environment permissions 和 Astro Contentful 指南。
给Claude Code的提示词要具体
不要只写“接入Contentful”。更好的提示词应该包含 API、文件、locale、预览和验证方式。
请为这个仓库实现Contentful博客集成。
- 已发布内容只使用Content Delivery API。
- 预览模式才使用Content Preview API。
- Content Management API token只能用于scripts/setup-contentful-model.ts。
- 默认locale为zh-CN,同时保留en-US参数。
- Next.js使用Draft Mode与revalidatePath处理预览和Webhook。
- Astro通过getStaticPaths在构建时读取Contentful。
- Preview token和Management token不得暴露到浏览器。
- 最后列出修改文件和验证命令。
这个提示词的作用不是让 Claude Code 写得更“漂亮”,而是让审查更容易。如果它把 CONTENTFUL_PREVIEW_TOKEN 放进客户端组件,或者在预览时仍然连接 cdn.contentful.com,问题会非常明显。
先按用例设计content model
Contentful 的优势是结构化内容。为了赶进度把所有内容塞进一个 Rich Text 字段,短期能上线,长期会影响多语言、CTA、分析和编辑体验。至少把常见用例拆开看。
| 用例 | 典型字段 | 缓存策略 | 业务目标 |
|---|---|---|---|
| 技术博客 | title、slug、excerpt、body、heroImage、author、tags、publishedAt | SSG + 发布Webhook重新验证 | 免费资料、相关文章、培训咨询 |
| 产品落地页 | headline、sections、pricingCopy、faq、ctaLabel、ctaUrl | ISR时间较短,重要更新手动revalidate | 购买、预约演示、咨询 |
| 文档站 | category、version、body、relatedDocs、updatedAt | SSG为主,同步搜索索引 | 付费模板、支持服务 |
| 多语言新闻 | 本地化title/body、region、canonicalSlug | 按locale生成页面 | 地区化CTA与销售线索 |
我在一个测试项目里踩过的坑,是把博客和产品页都放进 blogPost。第一篇文章能显示,但落地页需要价格说明、FAQ、CTA实验标识和转化事件。编辑只能把按钮文案写进正文,后来想做点击统计和A/B测试就很麻烦。Claude Code 能帮你重构,但最好一开始就把内容结构设计清楚。
环境变量、locale与权限要写成清单
环境变量建议从 .env.example 开始。这样 Claude Code 能看到哪些变量是公开读取、哪些是预览、哪些是管理操作。
CONTENTFUL_SPACE_ID=your_space_id
CONTENTFUL_ENVIRONMENT=master
CONTENTFUL_DEFAULT_LOCALE=zh-CN
CONTENTFUL_DELIVERY_TOKEN=delivery_token_for_published_content
CONTENTFUL_PREVIEW_TOKEN=preview_token_for_drafts
CONTENTFUL_MANAGEMENT_TOKEN=management_token_for_scripts
CONTENTFUL_PREVIEW_SECRET=random_secret_for_draft_mode
CONTENTFUL_REVALIDATE_SECRET=random_secret_for_webhooks
NEXT_PUBLIC_SITE_URL=http://localhost:3000
最危险的错误是给 Preview token 或 Management token 加上 NEXT_PUBLIC_。在 Next.js 中,这类变量会进入浏览器端 bundle。Preview token 能读取未发布内容,Management token 能修改空间,它们都只能留在服务端、本地脚本或可信 CI。
locale 也要明确。中文站常见设置是 zh-CN、zh-Hans 或企业自定义 locale,不能假设默认就是中文。如果查询里没有传 locale,Contentful 可能返回默认语言、fallback 内容,或者返回空字段。每个获取函数都应该接收 locale 参数,URL 里的语言也要和 Contentful locale 建立映射。
建一个类型化的获取层
下面的代码把 Delivery 和 Preview 的差异集中在一个 preview 参数里。Next.js 页面、Astro 页面、Webhook 处理都可以调用同一组服务端函数。
// src/lib/contentful.ts
import { createClient, type EntryFieldTypes, type EntrySkeletonType } from "contentful";
type BlogPostFields = {
title: EntryFieldTypes.Symbol;
slug: EntryFieldTypes.Symbol;
excerpt: EntryFieldTypes.Text;
body: EntryFieldTypes.RichText;
heroImage: EntryFieldTypes.AssetLink;
tags: EntryFieldTypes.Array<EntryFieldTypes.Symbol>;
publishedAt: EntryFieldTypes.Date;
};
export type BlogPostSkeleton = EntrySkeletonType<BlogPostFields, "blogPost">;
function required(name: string): string {
const value = process.env[name];
if (!value) throw new Error(`${name} is required`);
return value;
}
export function getContentfulClient(options: { preview?: boolean } = {}) {
const preview = options.preview ?? false;
return createClient({
space: required("CONTENTFUL_SPACE_ID"),
environment: process.env.CONTENTFUL_ENVIRONMENT ?? "master",
accessToken: preview
? required("CONTENTFUL_PREVIEW_TOKEN")
: required("CONTENTFUL_DELIVERY_TOKEN"),
host: preview ? "preview.contentful.com" : "cdn.contentful.com",
});
}
export async function getBlogPostBySlug(
slug: string,
options: { locale?: string; preview?: boolean } = {},
) {
const locale = options.locale ?? process.env.CONTENTFUL_DEFAULT_LOCALE ?? "zh-CN";
const response = await getContentfulClient(options).getEntries<BlogPostSkeleton>({
content_type: "blogPost",
"fields.slug": slug,
limit: 1,
include: 2,
locale,
});
return response.items[0] ?? null;
}
当 content model 变大时,可以从 Contentful 模型生成 TypeScript 类型,并让 CI 检测差异。无论用手写类型还是生成类型,关键都是让字段 ID、content type ID、locale 和 preview 状态变成可审查的代码,而不是散落在页面组件里。
Next.js、Astro与缓存策略
Next.js 适合需要预览和按路径再验证的页面。公开页面可以静态生成,预览页面通过 Draft Mode 使用 Preview API,Contentful 的 publish/unpublish Webhook 调用 revalidatePath。注意查看当前版本的官方文档:Next.js draftMode 和 revalidatePath。尤其是新版本中 draftMode 是异步函数,直接复制旧代码会出错。
Astro 更适合稳定的静态输出。用 getStaticPaths 在构建时读取所有 slug,然后渲染为 HTML。问题在于,Contentful 更新后页面不会自动变,必须让 Webhook 触发平台重新构建,或者把变化频繁的页面放在 Next.js 里做按需再验证。博客、文档、知识库用 Astro SSG 很适合;每天调整价格文案和 CTA 的落地页则更适合 ISR。
发布前重点检查这些失败例
| 失败例 | 表现 | 修复 |
|---|---|---|
| Preview token发到Delivery host | 401或看不到草稿 | preview时切换到preview.contentful.com |
| Delivery token用于预览 | 草稿页返回null | Draft Mode使用Content Preview API |
| Management token暴露到浏览器 | 严重泄露风险 | 只放在脚本和CI服务端 |
| 忘记locale | 语言错误或字段为空 | 每次查询传入locale |
| 图片asset没有publish | 文章有内容但图片缺失 | entry和asset都要发布 |
| Webhook在保存时触发 | 编辑过程中频繁清缓存 | 只监听publish/unpublish |
| field ID被重命名 | 前端类型和GraphQL schema断裂 | 保留API identifier |
上线前不要只看本地开发服务器。Next.js 的再验证要用接近生产的 build 检查,Astro 要检查构建产物和部署平台的 rebuild hook。让 Claude Code 在最后输出“每条路由使用的 token、host、locale、path”,可以发现很多隐藏问题。
把CMS结构连接到收入路径
Contentful 集成不只是技术任务,也会影响收入路径。建议把 ctaKind、ctaLabel、ctaUrl、relatedPosts 设计成结构化字段,而不是全部写进正文。技术教程可以引导到 免费资料,团队落地可以引导到 培训与咨询,模板型内容可以引导到 产品页面。
这样做的好处是,编辑可以改文案,工程侧仍然能保持统一组件和统一分析事件。实际测试后,我发现只要先把 Delivery、Preview、Management 的责任分开,Claude Code 生成的差异会小很多,预览和 locale 的问题也更容易在 review 阶段被发现,而不是等到发布后才补救。
免费 PDF: Claude Code 速查表
输入邮箱即可获取一页 PDF,整理常用命令、审查习惯和安全工作流。
我们会妥善保护你的信息,不发送垃圾邮件。
把 Claude Code 变成真正能带来结果的工作流
先领取中文说明的免费 PDF,再进入英文商品页选择合适的教材。如果你需要团队落地、流程设计或内容变现支持,也可以直接咨询。
关于作者
Masa
专注 Claude Code 实务流程、团队导入和内容转化的工程师。
相关文章
从Obsidian到CLAUDE.md的Claude Code流程:不再反复解释上下文
把 Obsidian 工作笔记整理成 CLAUDE.md 运行说明,让 Claude Code 每次都带着正确上下文开始。
Claude Code 收入 CTA 路由:从文章分流到 PDF、Gumroad 与咨询
用 Claude Code 按读者意图把文章流量分到免费 PDF、Gumroad 教材或咨询入口。
Claude Code 团队交接规则: 把审查证据、权限、回滚和收入路径一起交付
面向团队的 Claude Code 交接格式: 证据、权限、回滚、免费 PDF、Gumroad 与咨询路径都要可审查。