Next.js 博客接入 Decap CMS 完整教程(GitHub OAuth)

ShuaiQi
#建站#Decap CMS#Next.js

博客文章全用 Markdown 存 GitHub,每次发文都要手敲 frontmatter、提交、推送,格式还容易写错。接入一个 CMS 之后,可以在网页后台用可视化编辑器写文章,点发布就自动 commit 到仓库,静态站点重新构建即可生效。

这篇文章记录给 Next.js 博客接入 Decap CMS(原 Netlify CMS)的完整过程,包括后台页面、config.yml、GitHub OAuth 授权服务,以及一个很典型的坑。

为什么选 Decap CMS

  • 免费:不需要服务器,不需要数据库,只是一个静态页面 + GitHub API
  • 基于 Git:文章就是仓库里的 Markdown,随时可以退回纯手动流程
  • 无后端:内容直接读写 GitHub,静态博客天然契合

对比 Strapi、Contentful 这类方案,它们功能更强但需要额外部署后端或付费,个人博客用不上。

第一步:准备后台页面

在 public/admin/ 下新建两个文件。

public/admin/index.html:

html
<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta name="robots" content="noindex" />
    <title>内容管理</title>
  </head>
  <body>
    <script src="https://unpkg.com/decap-cms@^3.0.0/dist/decap-cms.js"></script>
  </body>
</html>

meta robots 一定要写 noindex,否则搜索引擎会把后台页面也收录进去。

第二步:写 config.yml

public/admin/config.yml:

yaml
backend:
  name: github
  repo: yourname/your-repo
  branch: main
  base_url: https://oauth.example.com
  auth_endpoint: auth

media_folder: "public/images"
public_folder: "/images"

collections:
  - name: blog
    label: 博客文章
    folder: content
    create: true
    slug: "{{slug}}"
    fields:
      - { label: 标题, name: title, widget: string }
      - { label: 路径标识, name: slug, widget: string, required: false }
      - { label: 发布日期, name: date, widget: datetime, date_format: "YYYY-MM-DD", time_format: false }
      - { label: 标签, name: tags, widget: list, required: false }
      - { label: 摘要, name: description, widget: text }
      - { label: 正文, name: body, widget: markdown }

几点说明:

  • folder 要和博客实际存放 Markdown 的目录一致,本站是 content
  • slug 用 {{slug}} 会自动按标题生成文件名,中文标题会变成拼音或原字符,建议手动填英文短横线形式
  • date_format 只保留日期,避免 frontmatter 里出现带时区的长字符串

第三步:部署 GitHub OAuth 授权服务

Decap CMS 登录要经过 GitHub OAuth,必须有服务端保管 client_secret,所以需要一个授权服务。官方的做法是部署一个现成模板,社区版本很多,搜索 netlify-cms-oauth 可以找到。

大致流程:

  1. GitHub → Settings → Developer settings → OAuth Apps → 新建
  2. Homepage URL 填博客域名,Authorization callback URL 填授权服务的回调地址
  3. 拿到 Client ID 和 Client Secret
  4. 把授权服务模板部署到 Vercel / Cloudflare Workers,配置这两个环境变量
  5. 把平台分配的域名填回 config.yml 的 base_url

第四步:绕开默认域名打不开的问题

这是最容易卡住的地方。授权服务部署在 Vercel 后,默认的 xxx.vercel.app 域名在国内经常无法访问,表现为点「登录」后页面一直白屏或者报网络错误。

解决办法是给这个项目绑定自己的域名:

  1. 在 Vercel 项目设置里添加自定义域名,例如 oauth.example.com
  2. 到 DNS 服务商加一条 CNAME 记录指向 Vercel
  3. 等证书签发完成后,把 config.yml 的 base_url 改成 https://oauth.example.com
  4. 同步修改 GitHub OAuth App 里的回调地址,否则会提示 redirect_uri 不匹配

改完重新部署,后台就能正常登录了。

第五步:静态导出的路由问题

本项目用的是 output: 'export',public/admin/index.html 会被原样复制到 out/admin/index.html。访问 /admin/ 时需要服务器把目录请求映射到 index.html,Apache 默认支持,Nginx 需要:

nginx
location /admin/ {
    index index.html;
    try_files $uri $uri/ /admin/index.html;
}

如果访问 /admin/ 出现 404,先查这里。

使用体验

接好之后,写文章的流程变成:打开 /admin/ → 新建文章 → 填标题和标签 → 写正文 → 发布。CMS 会直接向仓库提交一个 commit,等到静态站点重新构建完成,文章就上线了。

图片上传会存到 public/images,Markdown 里自动写入 /images/xxx 的路径,和 Next.js 的静态资源规则一致。

常见问题

登录后提示 404 Not Found?

八成是 base_url 写错或 OAuth 回调地址没同步修改。检查 GitHub OAuth App 的 callback URL 是否和授权服务实际地址完全一致。

发布后网站没更新?

Decap CMS 只负责提交到 GitHub,不负责构建。如果你的站点是手动上传 out/,需要重新 npm run build 再部署一次。

中文文件名的文章会不会出问题?

能正常生成,但 URL 会变成一长串百分号编码,分享和统计时不好看。建议在 slug 字段手动填英文。

后台页面能被别人访问吗?

能访问,但没有 GitHub 权限就无法登录和修改。额外建议在服务器上给 /admin/ 加一层访问限制,或者只在内网使用。

能不能不用 OAuth 直接填 Token?

Decap CMS 支持 local_backend 本地模式开发,但线上必须走 OAuth,不要试图把 token 写进前端代码。

相关阅读

评论