返回博客
Next.jsMDXSSGWebhook缓存策略内容系统

Next.js 内容系统实践:基于 GitHub、MDX 与 Webhook 的加载与缓存方案

结合实际项目,介绍如何基于 GitHub、Next.js、MDX、SSG 与 Webhook 构建内容系统,实现内容加载、缓存更新,以及“部分预渲染 + 登录后加载完整内容”的方案。

RaytonX
2 min read

在做内容型产品(课程、文档、博客)时,通常会遇到几个核心问题:

  • 内容放哪里?数据库还是文件?
  • 如何兼顾 SEO 和权限控制?
  • 内容更新是否需要重新部署?
  • 如何避免客户端直接暴露数据源?

这篇文章分享一种我们在实际项目中使用的方案:

基于 GitHub + Next.js + MDX,实现 SSG 预览 + 登录后加载完整内容


核心思路

整体设计可以拆成四层:

  • GitHub:内容存储(私有仓库)
  • 服务端:内容读取、缓存与权限控制
  • SSG 页面:预渲染部分内容
  • 客户端:登录后加载完整内容

1. 内容来源:GitHub API

内容统一存放在 GitHub 私有仓库(MDX 格式),通过 API 获取,而不是在 build 阶段下载到本地。

这样带来的好处:

  • 内容更新不需要重新部署
  • 支持 Git 工作流(PR、版本管理)
  • 内容仓库可以独立维护

底层通过一个 loadMdx 方法,从 GitHub 拉取 MDX 原始内容。


2. 统一内容入口(服务层)

为了避免页面、API、缓存各自直接访问 GitHub,需要抽一层统一内容服务,负责:

  • 组合课程元数据与正文内容
  • 提供统一的内容访问入口
  • 在这一层实现缓存策略

后续 SSG 页面刷新内容 API 全部依赖这一层。


3. SSG 渲染:只输出预览内容

页面在构建阶段通过 SSG 渲染,只输出“部分内容”,用于:

  • 首屏展示
  • SEO 收录

这样可以在保证性能的同时,为后续的权限控制预留空间。


4. 登录后加载完整内容

完整内容不会在 SSG 阶段输出。用户登录后,通过客户端请求内部 API:

  • 服务端校验登录态
  • 调用内容服务(命中缓存)
  • 返回完整 MDX 内容

整个过程不会直接访问 GitHub API,从而避免数据源暴露,并保证权限控制在服务端完成。


5. 缓存与内容更新

内容读取统一走服务层缓存,避免每次请求直接访问 GitHub。

当内容更新时,通过 Webhook 主动触发刷新:

  1. GitHub 仓库 push
  2. 触发 Webhook
  3. 调用服务端 /content-revalidate
  4. 执行:
    • revalidateTag:刷新服务层缓存
    • revalidatePath:刷新对应的 SSG 页面

这样可以在不重新部署的情况下,更新页面内容。


6. 方案的限制

需要注意:

revalidate 只能更新已有页面,不能生成新的 SSG 页面

也就是说:

  • 已有内容 → 可以更新
  • 新增页面 → 不会自动参与 SSG

如果希望新页面也使用 SSG,仍然需要重新部署。


推荐策略

在实际项目中,可以这样组合:

  • 内容更新 → Webhook + revalidate
  • 新增路由 → 自动触发部署

这样可以在更新效率与系统稳定性之间取得平衡。


总结

这套方案本质上是:

SSG + 内容 API + 缓存 + Webhook 的组合

它解决了几个关键问题:

  • 内容更新不依赖重新部署
  • 保留 SSG 的 SEO 与性能优势
  • 支持登录后的内容权限控制
  • 避免客户端直接暴露数据源

如果你对具体实现细节(如内容加载、缓存策略、Webhook 处理等)感兴趣,可以直接查看我们的项目:https://github.com/raytonx-labs/raytonx-learn