Astro 使用 Keystatic CMS 无头后端 - 实战演练
🎉 本文分享了博主给 Astro 添加 Keystatic CMS 无头后端的实战操作,包括相应代码编辑,Github “通行证”申请,Cloudflare 部署,以及遇到的相关问题,坑点等等,都进行了详尽的记录。
最近博主一直在折腾 Astro 的无头后端,之前尝试了 Decap CMS , 因为界面和预览都比较丑,所以决定换一个 CMS,网上找了一圈,感觉 Keystatic 似乎还可以,那么这次就来试试它吧。

1. Keystatic 是什么?
Keystatic 是一款通过现代可视化界面管理本地文件的 Git-based 无头 CMS,它将 Notion 般的富文本编辑体验(也支持 mardown),直接嫁接在你的代码仓库之上,无需配置数据库,就能通过自动化的 Git 提交来实现“内容即代码”的类型安全管理与无缝协作。
它是如何运作的?
不同于传统 CMS 需要通过 API 调取远程数据库,Keystatic 的逻辑非常“直脑筋”:
- 开发环境下: 它直接读取电脑磁盘上的文件。在网页界面点“保存”,它就直接修改你硬盘上的
.md或.json。- 生产环境下: 它通过 GitHub API 与你的仓库通信。你在管理后台点“发布”,它会自动帮你完成一次 Git Commit 或发起一个 Pull Request。
Github 1.9K Star 地址:https://github.com/thinkmill/keystatic
2. 本地测试
首先在本地进行测试,安装比较简单,直接在 astro 项目中,输入以下代码进行安装:
npm install @keystatic/core @keystatic/astro
如果你用 pnpm,就改成 pnpm然后配置 keystatic.config.ts文件
// keystatic.config.ts
import { config, fields, collection } from '@keystatic/core';
export default config({
storage: {
kind: 'local',
},
collections: {
posts: collection({
label: 'Posts',
slugField: 'title',
path: 'src/content/posts/*',
format: { contentField: 'content' },
schema: {
title: fields.slug({ name: { label: 'Title' } }),
content: fields.markdoc({ label: 'Content' }),
},
}),
},
});具体的字段,可以让 Ai 帮你写。
配置完,访问:http://localhost:4321/keystatic
即能打开你 Astro 的 keystatic 后台了。其界面也算简洁美观了。
3. 远程部署
Keystatic 可以部署到 Vercel、Cloudflare Pages、Netlify 等免费 Serverless 平台上。
本次尝试部署到 Cloudflare Pages 上。此时有两种部署方式,一是使用 GitHub 模式,二是使用 Keystatic Cloud 模式,下面是其简单对比:
| 比较维度 | GitHub 模式 (kind: ‘github’) | Cloud 模式 (kind: ‘cloud’) |
|---|---|---|
| 本质 | 你自己配置一个 GitHub App | 使用 Keystatic 官方的 GitHub App |
| 上手难度 | 高。你得去 GitHub 设置 OAuth 密钥、环境变量、Webhook 等。 | 极低。在官网点点鼠标,复制一个 Project ID 搞定。免费版可以添加最多3个用户. |
| 鉴权逻辑 | 每个团队成员都必须有该 GitHub 仓库的写权限。 | 成员通过 Keystatic Cloud 登录,不需要 GitHub 权限(由 Cloud 统一操作)。 |
| 额外功能 | 纯内容同步。 | Cloud Images。能自动优化图片,不让仓库因大图变得臃肿。 |
因为,如果使用 Keystatic Cloud 模式,即引入了第三方服务,从隐私方面考虑,本次决定先尝试使用 GitHub 模式。
(1). 手动配置 @astrojs/cloudflare:
执行:
npx astro add cloudflare(2). 修改 astro.config.mjs
示例如下:
import { defineConfig } from 'astro/config';
import cloudflare from '@astrojs/cloudflare'; // 必须显式引入
import keystatic from '@keystatic/astro';
export default defineConfig({
output: 'server',
adapter: cloudflare({
platformProxy: { enabled: true }, // 方便本地模拟 CF 环境
}),
integrations: [
keystatic(),
// ... 其他合并后的 plugins
],
});(3). 去 GitHub 申请“通行证” (GitHub App)
- 新建 App:去 GitHub Settings -> Developer settings -> GitHub Apps -> New GitHub App。
- 设置权限:你要给这个 App “Contents: Read & Write” 权限,否则它没法帮你发文章。
- 回调地址 (Callback URL):这是最容易错的地方。你必须填入你的真实域名:
https://你的自定义域名/api/keystatic/github/oauth/callback - 生成秘钥:你会得到一个
Client ID和一个Client Secret(这是一串乱码,只显示一次)。
(4):在部署平台 CF 录入变量
你得在 Cloudflare Pages 的后台,手动录入这些像“通关密码”一样的环境变量:
KEYSTATIC_GITHUB_CLIENT_ID=你的IDKEYSTATIC_GITHUB_CLIENT_SECRET=你的秘钥KEYSTATIC_SECRET=一段你自己随便编的随机字符串(用于加密 Cookie)
完善上述所有操作后,尝试访问网站后台:https://域名/api/keystatic
(5). 结果
一顿混乱,不停遇到各种报错,包括:
- CF 部署失败;
- CF 部署成功,但是打开网站,显示:Error 1101 Worker threw exception;
- CF 部署成功,网站正常打开,但是后台地址,显示:
[object Object]- 尝试 修改 Cloudflare 的兼容性 Flag:
- 在 Cloudflare Pages 的 Settings -> Functions -> Compatibility Flags 中,手动添加这一条:disable_nodejs_process_v2
- 修改后,后台页面不再显示
[object Object],而是显示,login with github,但是,点击后,又显示:Authorization failed - Ai 说是:@keystatic/astro 5.x 已知 bug,要降到 4.x 版本;按其给的代码修改,“@keystatic/core”: “^4.5.0”, // 或最新 4.x,和 “@keystatic/astro”: “^4.x.x” // 匹配对应版本 --- 结果,很坑爹: CF 部署直接报错!
- 尝试 修改 Cloudflare 的兼容性 Flag:
避坑:
- 在 Astro 5.x 里,
output的选项只剩下两个:
static: 全部静态。server: 开启服务端能力(包括原来的server和hybrid)。
4. 总结:
一顿操作猛如虎,折腾大半天,愣是搞不定,
Keystatic官网以及网上几乎没有相关教程,ai 更是坑爹,纯纯的浪费时间。
暂时只能放弃部署 Keystatic,有大佬知道怎么回事的,请在评论区指点一下吧。





