给静态博客装评论区:选型三十秒,缝合一晚上
风林集是纯静态站:Astro 出页面,Cloudflare Pages 托管,代码放在 GitHub。好处是没有服务器可以坏,坏处是没有服务器可以干别的事——比如存评论。
评论系统我选了 Giscus。它的思路是把评论存成仓库里的 GitHub Discussions,等于拿 GitHub 白嫖一个数据库:零成本、零维护,而且发言必须登录 GitHub,这道门槛顺手挡掉了绝大多数垃圾评论。代价是读者得有个 GitHub 账号,路人会被挡在外面。想了想,接受——技术博客本来也不是写给路人看的。
选型快,是因为选择题提前问完了。自建 Cloudflare D1 要写后端,Waline、Twikoo 要部署服务,全违背”没有服务器”的初衷。Giscus 是唯一不增加运维面积的选项。
第一道坎:仓库得是公开的
Giscus 有个硬性前提:仓库必须公开,因为评论数据就明晃晃地存在仓库的 Discussions 里。huo241/fenglinji 当时是私有的。
转公开之前先做了安全扫描——当前文件加上全部 git 历史,检索 ghp_、github_pat_、sk-、AKIA 这些密钥特征,干净,才敢动手。这一步省不得:历史提交里躺过的密钥,转公开等于当场泄密。
中间还有个小插曲。操作仓库需要一个 GitHub token,我以为昨天发过,让助手自己找。实际昨天的令牌是”用完即焚”,没落盘,对话里也翻不着。最后是在 macOS 钥匙串里找到的——git 的 osxkeychain 凭据里存着一个可用的 token。这条经验值得记下来:本机的密钥,先翻钥匙串,别去翻人的记忆。
三处缝合
代码本身不难。giscus 官方给一段 <script> 贴上去就能用,难的是你的站不是”默认站”:有视图转场、有两套主题、评论区躺在毛玻璃卡片里。总共缝了三针。
第一针,主题。 站点是深色/纸墨两档换肤,giscus 官方默认皮放在哪一档都不搭。做法是抓官方 light.css 和 transparent_dark.css 当底稿,用 Python 正则覆盖 CSS 变量——不重写整套,只改变量,保证变量集完整不缺项。纸墨档:画布透明、墨字、朱砂主色;夜航档:画布透明、浅字、雾蓝主色。
画布透明这一步最值。giscus 的评论区渲染在 iframe 里,iframe 不自带底色——把主题画布设成透明,博客容器那层磨砂卡片就直接透出来,不用在 iframe 里模拟毛玻璃,两层毛玻璃叠在一起是灾难。
第二针,转场。 Astro 的 ClientRouter 做视图转场,切页之后整个 DOM 是新的,giscus 的 script 不会自己重新挂载。监听 astro:page-load 事件重挂即可。换肤则是另一条路:MutationObserver 盯着 <html> 上 data-theme 和 data-glass 两个属性,一变就向 iframe postMessage,让 giscus 现场换皮。评论区的映射用 pathname 定位,语言 zh-CN,lazy 加载——不打扰首屏。
第三针,CORS。 这是上线后才炸的。WebKit 控制台报 Origin https://giscus.app is not allowed by Access-Control-Allow-Origin——giscus 拉自定义主题用的是 fetch,而主题 CSS 托管在 Cloudflare Pages 上,默认不允许跨域。在 _headers 里给主题 CSS 加一行放行:
/giscus-*.css
Access-Control-Allow-Origin: https://giscus.app
报错信息指哪打哪,五分钟解决。但如果不看控制台,你只会看到一个”加载中”卡死,无从下手。
顺手修的两件小事
一,giscus 官方在 night 主题里藏了个 #238636 的 GitHub 绿,主按钮就是它。在雾蓝配色里,这颗绿按钮像宴席上坐着个外卖骑手。补丁:染雾蓝、字用深色。
二,本来想给 Discussions 建个「文章评论」专用分类,实测 GraphQL 里没有 createDiscussionCategory 这个 mutation——分类只能在网页上建。作罢,改用默认的 Announcements 类型,只有维护者能开新讨论、读者只能回复,恰好是 giscus 官方推荐的防灌水形态。有时绕路绕不通,发现路本来就该这么走。
部署那点波折
git push 走本机代理,对 GitHub 时好时坏,两个 commit 推不上去。curl 直连 GitHub API 却正常——那就绕开 git,改用 Contents API PUT 直推。代价是本地和远端出现了同内容不同 sha 的分叉,等代理恢复后 git pull --rebase 平掉即可。工具抽风的时候,别死磕,换条路走,把账记下来以后还。
验证
构建 12 页全绿;线上主题 CSS 返回 200、CORS 头生效;WebKit 实测两档主题截图,纸墨档朱砂按钮配宣纸底,夜航档雾蓝按钮配透明画布。最后是 giscus 控制台里那行:
Discussion not found. A new discussion will be created

这是好消息——App 已装、API 已通,第一条评论发出来, Discussions 就会自动建好。评论区的第一句话,还空着。
评论