从 Markdown 到 Tiptap:个人博客内容系统的结构化改造
一次真实的内容系统迁移:从文件型 Markdown 转向可校验、可版本控制、可复用渲染的 Tiptap JSON。

最初的博客使用 Markdown 与 MDX 文件维护文章。它适合开发者快速开始,但当内容需要后台编辑、图片上传、自动保存、表格和项目复用时,文件格式逐渐变成了产品能力的边界。
问题不是 Markdown 本身
Markdown 仍然适合代码仓库文档。真正的问题是:博客后台必须让编辑者理解语法、图片插入依赖字符串拼接、前端渲染依赖一组 remark/rehype 插件,而且服务端无法可靠理解正文结构。
新的文档协议
文章保存四个互补字段:content_format 标识格式,content_json 保存 Tiptap 文档,content_text 支持搜索与摘要,content_version 用于乐观锁。
type Document = {
type: 'doc'
content: Block[]
}后端必须做什么
校验根节点必须是 doc
只接受标题、段落、列表、引用、代码、图片和表格等白名单节点
限制 bold、italic、link、code 等 mark 类型
递归提取纯文本,而不是信任客户端额外提交的摘要
更新时比较 contentVersion,避免多个页面互相覆盖
前端为什么不用 HTML 字符串
公开页面根据节点类型创建 React 元素,链接协议也会校验。这样可以保留结构化文档的能力,同时避免把后台内容直接交给 dangerouslySetInnerHTML。
迁移策略
旧文章继续按 Markdown 渲染,保证已有链接可访问
进入编辑页时用 Tiptap MarkdownManager 转成 JSON
新保存内容统一写入 tiptap 格式
确认所有内容完成重建后,再移除本地 MDX 数据源
项目与文章共享能力
项目详情原本仍是 Markdown textarea。改造时没有再维护第二套编辑器,而是给 Project 增加同样的 JSON、纯文本和版本字段,并复用工具栏、斜杠菜单、图片上传和 Renderer。
编辑器解决表达体验,文档协议解决长期维护。两者不能混为一谈。
最终检查
Go 内容校验测试
ESLint 与 TypeScript
Next.js 生产构建
真实 API 创建、读取与版本冲突验证
浏览器检查目录、表格、代码和移动端布局