本文介绍本站从 Giscus 迁移到 Waline 的原因、现在的评论与浏览量架构、历史数据迁移方法,以及访客评论和双语邮件通知的配置方式。
现在打开任意文章,评论区已经换成了新的 Waline 界面。读者不需要 GitHub 账户,可以直接以访客身份参与讨论;如果希望在评论收到回复时得到通知,还可以选择填写邮箱。

为什么从 Giscus 迁移
Giscus 是一个很适合技术博客的评论方案:它把评论保存在 GitHub Discussions,维护成本低,也很符合开源社区的使用习惯。问题是,发表评论需要登录 GitHub。
本站的内容已经不只面向开发者。工具介绍、马耳他生活信息、旅行内容和网站更新会吸引不同背景的读者。要求每位读者先拥有并登录 GitHub,实际上为一次普通留言设置了不必要的门槛。
迁移到 Waline 主要是为了获得以下能力:
- 支持访客评论,不强制注册或登录;
- 邮箱选填,并可在评论收到回复时发送通知;
- 支持评论点赞、文章反应和评论数量统计;
- 将文章浏览量与评论系统放在同一套计数接口中;
- 提供独立的评论管理后台,不必进入 GitHub Discussions 处理内容;
- 保留中英文界面,并让通知邮件跟随文章语言。
访客可以不登录,但评论服务仍会为了限流、安全防护和管理处理必要的技术信息。昵称和评论内容会公开显示,邮箱则不会显示在评论区。
现在的托管结构
博客本身仍然是 Hugo 生成的静态网站,由 GitHub Actions 构建并发布到 GitHub Pages。内容编辑使用 Sveltia CMS,文章和页面最终仍保存到 GitHub 仓库。
新的评论系统分成两部分:
- Waline Server 部署在 Vercel,负责评论 API、管理界面、邮件通知和计数请求;
- 评论、用户、文章互动和浏览量数据存储在 Neon PostgreSQL。
这种拆分不会把整个博客变成动态网站。GitHub Pages 继续提供静态页面,只有评论区和计数在浏览器中按需请求 Waline API。即使评论服务暂时不可用,文章正文仍然可以正常访问。
仪表盘的管理选单也已经更新:
- 内容管理进入本站的 Sveltia CMS;
- 评论管理进入 Waline 管理界面。
仪表盘的系统信息现在会同时标明内容系统由 GitHub 托管,评论系统使用 Vercel 与 Neon。
评论区怎样融入现有主题
Waline 自带完整的输入框、评论列表、排序、Markdown、图片上传和表情选择功能,但默认视觉需要与 Stack 主题进一步协调。
我为评论区增加了一层主题适配,包括:
- 使用网站现有的卡片背景、边框、圆角和阴影变量;
- 同时适配浅色与深色模式;
- 把浏览量和评论数放进评论须知卡片;
- 保留移动端布局,避免输入框和用户信息被挤压;
- 根据文章语言切换界面文案;
- 使用 Twitter Emoji 风格的表情资源,保持不同系统上的显示一致。
文章反应目前提供“喜欢、好笑、思考、惊讶、难过”五种选择。它们使用 Waline 的 Twitter Emoji 图片资源,而不是读取访客电脑中的本地表情文件,因此不同浏览器会看到一致的图案。
从 Cloudflare 迁移浏览量
本站原来的浏览量系统运行在 Cloudflare Workers 与 D1 上,其中还合并了此前的 GA4 历史数据。迁移评论系统时,我没有从零重新计数,而是把已有统计带到 Waline。
迁移快照中,Cloudflare D1 有 82 条原始计数键。部分中文路径同时存在百分号编码和 Unicode 两种形式,例如同一页面可能分别以编码后的中文 URL 和直接中文 URL 出现。
迁移过程先对路径做规范化,再把相同页面合并,最终得到 76 个唯一 URL。全站累计浏览量在迁移时为 1,607。
目标数据库使用 Waline 的 wl_counter 表。迁移时还处理了一个容易忽略的问题:该表默认只以数字 ID 为主键,没有强制要求 URL 唯一。早期通过公开 API 并发补数时,同一路径可能产生重复记录。
最终采用数据库事务完成整理:
- 每个 URL 保留一条计数记录;
- 合并并清理重复项;
- 为 URL 增加唯一索引;
- 使用“只增不减”的写入规则补齐历史数据;
- 核对缺失路径、重复路径和低于源数据的计数。
验证结果为 76 条目标记录、0 个重复 URL、0 个缺失 URL,并且没有任何页面低于 Cloudflare 的迁移快照。使用“只增不减”规则,也避免了迁移期间的新访问被历史数据覆盖。
全站页面怎样计数
新的计数并不只出现在文章页。网站页脚会在非 404 页面加载 Waline 的轻量浏览量模块,为当前页面增加一次访问,同时更新一个专门的全站累计计数。
文章评论区显示浏览量时只读取现有数字,不会再次递增,这样可以避免同一次页面加载被页脚和评论组件重复计算。
主页、归档、分类、标签、图片墙、链接页、仪表盘和中英文页面都使用同一套新计数系统。旧的 Cloudflare 浏览量接口不再负责前端统计。
邮件通知与双语模板
邮件通知通过 Vercel 环境变量配置。SMTP 账户、应用专用密码和数据库连接信息都保存在托管平台的敏感变量中,不会写入 Hugo 仓库、文章或前端代码。
配置项包括:
- SMTP 服务、发件账户和应用专用密码;
- 网站名称、网站地址和站长通知邮箱;
- 发件人名称与地址;
- 评论回复邮件与新评论通知邮件的标题和正文。
Waline 的邮件模板可以读取评论所属页面路径。本站中文文章都位于 /zh/ 下,因此模板会检查评论 URL:
|
|
中文文章下的评论会收到中文邮件,其他页面使用英文邮件。模板只引用评论者昵称、评论正文和文章链接,不会在邮件正文中暴露数据库凭据或其他系统密钥。
为了保护账户安全,SMTP 使用的是单独生成的应用专用密码,而不是邮箱账户的日常登录密码。密码更新后必须重新部署 Waline,新的环境变量才会进入生产函数。
评论数据是怎样迁移的
旧评论先导出为 Waline JSON 格式,再导入新数据库。迁移时保留了评论正文、文章路径、回复关系、发布时间和审核状态。
部分由站长发布的旧评论在导出时缺少用户关联信息。处理时只补齐管理员用户 ID、昵称、邮箱标识、主页和客户端信息,不修改原评论内容、页面、回复关系或时间。
这类修复很重要。如果只搬运文字而没有恢复用户关联,旧评论可能会被显示成普通访客留言,头像、站长标记和后续管理权限也会不一致。
隐私与评论须知
评论区现在使用以下提示:
本站支持访客评论。如果您希望获得评论回复通知,可以填写您的邮箱;收到回复时,系统将自动发送通知给您。
邮箱不是发表评论的强制条件。填写邮箱的主要用途是回复通知和头像匹配,不会在评论列表中公开显示。
由于评论系统会处理评论内容、可选邮箱以及必要的技术信息,本站的隐私政策也已经同步更新,说明 GitHub Pages、Vercel、Neon 和 Waline 在当前架构中的作用。
接下来
评论系统迁移已经完成,但它仍需要在真实使用中继续观察。我会关注邮件送达、移动端输入体验、反垃圾策略、数据库计数和不同语言页面的通知效果。
如果你在评论时遇到加载失败、通知未送达、路径计数不一致或界面问题,欢迎直接在本文下方以访客身份留言。