Strapi 5 深度定制:集成 Quill 与多租户架构实现
blog AI Technology

Strapi 5 深度定制:集成 Quill 与多租户架构实现

虽然 Strapi 5 是一款出色的无头 CMS,但我为 kuro.boo 进行了深度定制,使用 Quill 替换了 Lexical,并添加了基于数据库 Schema 的多租户功能。


2025年9月,“Strapi 5” 的发布为开发者带来了重大更新。它彻底告别了 Strapi 4 的数据结构,引入了破坏性变更、重构的多语言 API 并提升了性能。虽然它变成了一个更简单、更强大的工具,但一些默认配置仍有提升空间。

具体来说,默认的 “Blocks” 编辑器(基于 Lexical)虽然现代,但缺乏富文本排版设计中经常需要的进阶表格编辑和文本装饰工具。它甚至无法开箱即用地构建一个简单的表格。虽然表格边框在西方设计中不太常见,但在日本,它们对于创建结构化、易于阅读的页面至关重要。

此外,Strapi 5 缺乏原生的多租户支持。您可以为每个组织运行单独的容器,但为每个租户运行专用的 PostgreSQL 数据库成本高昂。为了实现低成本的多租户架构,我定制了后端。以下是我如何修改博客 “kuro.boo” 的 Strapi 5 environment,以实现极佳的编辑体验和高管理效率。


1. 解决日语输入法 (IME) 的异常行为

Strapi 基于 React 构建,这带来了一些特定的 UI 行为。Strapi 5 中的主编辑器在处理日语 IME 事件时存在细微问题,导致输入时光标会发生跳跃。我尝试了 macOS 上的三种不同输入法(Apple 默认输入法、谷歌日语输入法和 Kawasemi),但光标问题仍然存在,因为编辑器捕获了不必要的按键事件。起初,我不得不在 Zed 等外部编辑器中写好文章,然后复制粘贴过来。这太繁琐了。


2. 处理多图上传

文章不仅仅需要文本和封面图。我首先尝试了以下插件:


TipTap


TipTap 很流行且支持多张图片,但它的实现方式需要为每一张图片和每一个文本段落添加单独的输入块。这感觉很过时,远非真正的所见即所得 (WYSIWYG) 体验,让我想念起 Dropbox Paper(我经常使用它)的流畅排版工具。

3. 过渡到 Quill

由于 Lexical 和 TipTap 都不符合我的需求,我研究了 Quill。随着 v2 版本的发布,Quill 展现出了极佳的灵活性。它的所见即所得功能看起来很有前途,但仍然缺乏对高级表格的原生支持。为了解决这个问题,我集成了 “quill-better-table”(在调试了一天之后)。该插件允许通过右键单击添加/删除行和列、合并单元格以及直接在 Strapi 的后台管理面板中自定义单元格样式。关键是,这些表格会保存为标准的 HTML,从而易于在 Astro 前端中进行渲染。

这解决了表格编辑和输入法输入的问题,让我们在 Strapi 内部拥有了一个功能强大的所见即所得编辑器面板:


4. 添加拖拽图片上传功能

为了让写作更流畅,我添加了拖拽功能:拖拽图片或从剪贴板粘贴图片会自动触发 Strapi 的上传 API,将其注册到媒体库中并插入到编辑器中。(注意:由于拖拽操作不会显示超大文件的详细错误信息,我们仍需留意文件大小限制)。

5. 基于 Schema 的多租户架构

为了在单个 Strapi 实例中管理多个网站,而无需启动独立的数据库容器,我实现了在同一个数据库实例中切换数据库 Schema (DATABASE_SCHEMA)。这在保持数据库低成本的同时,为每个租户维护了独立、安全的数据库环境。


6. 本地优先的静态网站生成 (SSG) 工作流

虽然 24/7 运行 CMS 服务器对于协作团队来说是理想的,但对于个人博客或低频更新的网站来说,这增加了不必要的成本和安全风险。因此,我改变了部署架构:

  1. 仅在写作或编辑时启动本地 Strapi 实例。
  2. 运行开发构建,将 Strapi 内容编译成静态 Astro 页面,将图片复制到构建文件夹中并更新图片链接。
  3. 停止本地 Strapi 实例,并将完全静态的网站部署到 Cloudflare Pages。


这种设置意味着我们的公共网站完全托管在 Cloudflare 的边缘网络上。它加载速度极快,无需托管费用,并消除了公网数据库的安全风险。在 kuro.boo 上,为了方便起见,我让本地 Strapi 实例在我的本地机器上运行,因为它不产生托管费用。

默认设置与自定义设置的对比:

功能

默认设置

kuro.boo 定制

编辑器核心

Lexical (Blocks)

Quill (v2+)

表格编辑

有限

quill-table-better (支持单元格合并及样式设置)

租户

单数据库 / Schema

基于 Schema 的多租户

图片处理

手动上传

拖拽或粘贴时自动上传媒体文件

动态区域

标准选择器

集成批量图片上传面板

架构

常开型 CMS

仅限本地的 CMS,配合静态网站生成 (SSG)

构建/部署

手动 / 简单 Webhook

通过 GitHub Actions 自动部署

结论

我还解决了一个小 Bug,即任何微小的编辑都会更新文章的发布日期,从而将旧文章推送到信息流的顶部。我添加了一个专用的 `publishedAt` 字段并以此进行排序。虽然直接修改 Strapi 5 源码可能会使未来的升级变得更加困难,但这种程度的自定义正是无头 CMS 平台的强大之处。它允许我构建一个完全契合自身需求的编辑环境。

来源:

Strapi 5 文档

Quill - 富文本编辑器

quill-table-better (GitHub)