← 返回日报
精读 预计 3 分钟

My comment section is static HTML

摘要

作者介绍自己 Hugo 博客的评论实现:评论在构建时抓取并编译进页面,无 iframe、无第三方脚本、无追踪器,读评论和发评论都不依赖 JavaScript。评论数据存于独立的 Phoenix 服务器(Popsicle Boat),通过 API 创建线程、构建时拉取 JSON 渲染;发评论需登录账号,靠蜜罐、时间检查、限流等隐形手段防垃圾,无验证码。文章还说明了延迟(约一分钟)、依赖账号等代价,并给出 API 文档链接供他人复用。

荐读理由

静态评论方案可直接照搬:Hugo 构建时拉取 Phoenix 服务端的 JSON 渲染进页面,评论写入走独立服务,博客与评论系统解耦,照文档就能搭起同样架构

原文

My comment section is static HTML

Projects, Blogging

Well, that did something. Keep going. Nothing is hidden on this page, but some Weblog pages have letters that burn brighter than others. Congratulations! Hope you enjoyed the fire! 🔥 The fire isn't everything, though. One more click starts it over. When you've found and solved the real puzzle, you'll know.

Posting a comment does take a little more. It’s how I keep guard against bots and spammers, etc.

This blog is a Hugo site. It has a comment section. If you view source on any post with comments, you will find them in the HTML, because they are compiled into the page at build time like everything else. There is no widget, no iframe, no tracker, and no third-party script, and loading a post makes no request to any server but this one. The page does carry some JavaScript (the site search, a few small comforts), but the comments never need it: with JavaScript off you can read every comment and post one.

The shape

The comments live on a small Phoenix server I run, called Popsicle Boat. Each post has a companion thread there; publishing a post makes one API call that creates the thread and writes its URL into the post’s front matter. That URL is the only coupling between the two systems.

At build time, Hugo fetches each thread’s replies.json and renders the replies as plain HTML once per post per build, cached, capped indentation. If the server is unreachable, the build carries on and renders no comments. The comment system cannot break the blog.

Below the replies is a plain HTML form: a textarea and a submit button, POSTing to the boat. No script, no cookie, no request on pageview. The boat walks you through signing in if needed, you confirm, and it sends you back to the post with #just-posted on the URL. A hidden note appears via CSS :target to say your comment is on its way. It is: the boat pings my build hook, and about a minute later the comment is part of the page. One of the small comforts is that it refreshes for you when it lands. A manual refresh does the same.

Why this shape

Reading is static. Writing is dynamic. That is the whole idea.

A reader costs nothing and depends on nothing. The page they get here is the page I built, comments included. A writer touches the server once, at the moment of writing, which is the point where a server is not just useful, but like a moat: identity, spam defense, notifications. A comment writer is protected, a website owner (like me) is notified when written to.

The durability falls out for free. The comments are in my generated pages, so they stay with the blog no matter what happens to the comment server. Most comment systems get this backwards: the conversation lives on their infrastructure and your page borrows it at read time, every read, forever.

There is no captcha. Spam defense is the boat’s job and stays invisible: a honeypot, time-to-submit checks, rate limits, and the sign-in step itself. The boat is, to put it simply, the guard at the gate.

The honest costs

Comments lag by a build. About a minute here on this blog.

Commenting requires an account on the boat. That stops some people. I keep it because a signed name is what makes the no-captcha posture possible.

If the boat is down during a build, that build renders the affected posts without new comments until a later build picks them up. I prefer a page that sometimes forgets to a page that sometimes fails.

If you want this

The API is written up in one page: create a thread, get replies as JSON, point a build hook at your host. Documented at https://www.popsicleboat.com/for-bloggers/api — you mint your own token, shown once, to you. No one else sees it.

Lobsters · 1 赞 · 1 评 讨论 → 阅读原文 →

这条对你有帮助吗?