重新整理我的博客:从文章展示到内容管理

最近,我开始重新整理自己的博客。想把这一段时间做过的项目和学到的知识写下来,也想让更新这件事更容易持续。
网站原来的前端风格,我已经比较满意。这次更多精力放在后端和 Notion:文章怎么读取,修改之后怎么更新,不同语言的版本怎么关联,以及旧文章能不能继续被找到。
这些工作平时藏在阅读页面后面,但会直接影响我愿不愿意继续写,也影响读者能不能顺利读到。

先处理内容怎样到达网站

博客基于 Notionic 定制,使用 Next.js、React 和 JavaScript,内容放在 Notion,部署在 Vercel。
此前的内容读取依赖非官方接口。最近排查时,本地请求返回了 403 和 Cloudflare 拦截页面,云端构建也遇到了 403。
这个结果只能说明当时请求失败,不能单凭它判断数据库是否公开。已连接的 Notion 工具能够读取内容,也不代表网站使用的读取方式获得了同样的授权。
这次修缮把内容读取迁移到官方 Notion API,使用供网站读取的连接,并给博客数据库授予访问权限。
不过,切换 API 还涉及正文格式。原来的渲染器使用 recordMap,而官方 API 返回的是页面与块数据,需要经过适配,才能继续显示已有内容。Notion 官方文档也将页面正文作为块及其子块来读取。Notion 页面内容文档
所以这次也补了分页读取、嵌套块处理,以及常见正文类型的转换。页面能请求成功只是第一步,还要检查代码、公式、图片和实际文章是否正确显示。

为什么重新生成了,内容还是旧的

排查过程中,一个具体问题是服务端取数缓存没有有效期。
即使页面配置了重新生成,如果读取函数一直返回同一份缓存,生成出来的仍然会是旧文章。
我现在把这条链路分开理解:请求层决定什么时候重新向 Notion 取数据,页面层决定什么时候重新生成显示结果。两者需要配合。
当前默认刷新间隔是六十秒,但这不表示网站每六十秒轮询一次。ISR 由访问触发;低访问量页面通常要等后续请求才开始更新,后台生成和缓存也会影响读者看见新版的时间。Next.js 13 ISR 文档
我更关心的是,日常编辑内容可以通过这条链路更新,不必每次为改一段文字重新部署代码。

取数失败时,别丢掉还能读的文章

外部服务可能暂时失败。如果刷新失败就返回空正文,原本能读的页面反而会被替换掉。
这次调整让取数错误继续抛出,由 ISR 保留此前成功生成的页面,等待后续重试。这个回退依赖已经存在成功页面;第一次生成就失败时,没有旧版本可以使用。
本地生产模式的模拟验证覆盖了内容修改后更新、上游返回 503 时保留成功页面,以及恢复后继续更新。这些是模拟故障测试,真实正文和线上页面又做了单独检查。
这也让我更习惯区分几种证据:构建通过、模拟流程通过和浏览器里实际显示正确,各自回答不同的问题。

让 Notion 数据库更贴近写作

后端之外,我也整理了内容分类和编辑状态。
现在,一个数据库里统一管理文章、笔记、项目、随想、书架、独立页面和栏目介绍。不同视图帮助我找到正在写的内容、需要处理的译文,以及网站页面。
创建时间、发布日期和发布状态分别保留。创建一篇页面,不代表要马上公开;重新整理一篇旧文章,也不应该随意改变它原来的发布日期。
当前公开内容需要有标题,状态为 Published,并且发布日期已经到达。Draft 和未来日期内容不会进入公开列表。
这些条件让数据库里的编辑过程和读者看到的内容之间,有了明确的规则。

三种语言,要知道彼此是什么关系

博客有中文、英文和日文。以前维护三份内容,容易把版本对应和校对进度混在一起。
这次整理后,每个语言版本仍然是独立页面,译文通过 source 关联原文,网站的语言菜单依据关系寻找对应的已发布版本。
Notion 里的翻译计划记录希望补哪些语言,翻译管理记录译文处理到哪一步。它们用于组织编辑工作,不会自动翻译或发布。
迁移建立了二十六组内容的语言关系,并将五十二条译稿置于待校对流程。版本之间能够切换,和译文已经准确,是两件需要分别确认的事。
后续我希望原文变化时,也能清楚地知道哪些译文需要更新,同时保留人工修改。

文章地址不再需要手动填写

原来的文章依赖手动维护 slug。这次改为根据内容类型和 Notion 页面 ID 自动生成地址。
修改标题不会改变页面 ID,同名文章也能区分。英文与日文继续使用各自的语言路径。不过,内容类型决定地址前缀,修改类型仍然会影响地址。
删除数据库中的 slug 列之前,旧地址做了备份,并配置永久跳转。迁移记录分别验证了六十三个新页面和六十五个旧地址跳转。
对读者来说,已经收藏或分享过的链接,应该尽量继续可用。整理后台不能只看新页面是否漂亮,也要记得过去的入口。

这次整理,也留下了下一步

目前内容读取、数据库结构、多语言关联和自动地址已经完成相应修缮。评论服务配置、上传媒体签名地址过期的持久方案、主动刷新入口和自动翻译,仍有待处理。
我也想把第一个 Agent 项目和博客连接起来,让它协助搜集资料、准备草稿和整理译文,再由我审核决定发布。但那是接下来要实现的流程。
这次重整先为写作搭好了更清楚的基础。接下来,我希望真正填进去的,是最近做过的东西、遇到的问题,以及自己逐渐形成的理解。
网站:xinzhe.dev · 源码:Xinzhe.Blog
对于本文内容有任何疑问, 可与我联系.