在内容型项目中,我们经常会遇到几个现实问题:
- 不想维护数据库
- 不想自建 CMS
- 希望内容版本可追溯
- 希望写作流程尽量贴近开发习惯
- 同时又想要 SSG 的性能 + SEO
基于这些目标,我最终采用了一套工程化、低维护、可长期运行的方案:
GitHub Issue 作为内容源 Next.js App Router 在 build 阶段生成静态站点 GitHub Webhook 触发自动重新构建
这篇文章完整总结这套方案的设计思路与实现要点。
一、整体架构概览
先给出最终架构图(逻辑):
GitHub Issue(文章 / 专栏)
↓
GitHub GraphQL API
↓(build 阶段)
Next.js App Router(SSG)
↓
Vercel 静态部署
核心原则只有一句话:
👉 所有内容只在
next build阶段获取 👉 线上访问永远不请求 GitHub
二、为什么选择 GitHub Issue 作为内容源
1️⃣ 天然的 Markdown 支持
- Issue Body = Markdown
- 支持代码块、表格、图片、任务列表
- 和开发者写 README 的体验完全一致
2️⃣ 版本控制 & 历史可追溯
- 每一次修改都有记录
- 可以对文章内容回滚
- PR / Review / Comment 天然支持
3️⃣ 白嫖一个 CMS 后台
GitHub 自带:
- 编辑器
- 标签系统(Labels)
- 里程碑(Milestone)
- 搜索
- 权限管理
👉 不用写一行后台代码
三、内容模型设计(重点)
1️⃣ 基本映射关系
| GitHub | 博客系统 |
|---|---|
| Issue | 文章 |
| Milestone | 专栏(Series) |
| Label | 分类 / 状态 |
| Comment Count | 评论数 |
2️⃣ 推荐约定(非常重要)
Issue 约定
-
Title:文章标题
-
Body:文章正文
-
Labels:
post(表示可发布)draft/published
-
Milestone(可选):所属专栏
Milestone 约定
- Title:专栏名称
- Description:专栏简介
- Due date:专栏完结时间(可选)
四、为什么用 Next.js App Router + SSG
1️⃣ 目标很明确
- 页面是 内容型
- 更新频率低
- SEO 很重要
- 首屏速度优先
👉 SSG 是最合适的选择
2️⃣ App Router 的优势
- 原生支持
asyncServer Component - 原生支持
generateStaticParams - fetch 缓存语义清晰
- 不再需要
getStaticProps / getStaticPaths
ts
export const dynamic = "force-static"
export const dynamicParams = false
这两行,明确告诉 Next.js:
构建时生成所有页面,运行时不兜底
五、构建时拉取 GitHub 数据
1️⃣ 使用 GitHub GraphQL API
相比 REST API:
- 请求更少
- 字段可控
- 有 cost 概念,更适合 build-time
典型查询结构:
graphql
query GetPosts {
repository {
issues {
nodes {
title
body
milestone { title }
labels { nodes { name } }
}
}
}
}
2️⃣ 必须注意的一个坑:fetch 缓存
在 App Router 中:
ts
fetch(url, {
cache: "force-cache"
})
- build 阶段会缓存结果
- 如果你在构建过程中多次请求同一 query
- 很容易出现「数据不更新」
👉 解决方案:
- build 阶段允许缓存
- webhook 触发时重新 build
- 不在 runtime fetch GitHub
六、专栏(Series)是怎么做的
核心思想
Milestone = 专栏
这是 GitHub 官方设计就支持的用法。
专栏能力直接白嫖:
- 专栏名称
- 专栏简介
- 文章数量
- 完成进度(progressPercentage)
前端可以轻松做出:
- 专栏列表页
- 专栏详情页
- 阅读进度条
七、自动更新:GitHub Webhook + Vercel
工作流:
- 新建 / 编辑 Issue
- GitHub 触发 Webhook
- 调用 Vercel Deploy Hook
- 自动
next build - 生成新的静态站点
👉 整个过程 无需手动干预
八、性能 & Rate Limit 分析
GitHub GraphQL API:
- 每小时 5000 点
- 普通 Issue 查询 cost ≈ 1
实际情况:
- 一次 build 用几十点
- 每天 build 十几次都没压力
而线上访问:
- 0 GitHub 请求
- 完全静态资源
想法或问题?在 GitHub Issue 下方参与讨论
去评论