Inspired by some of my favorite blogs, and in search of my next funemploymentproject (July ‘23 update: I’m back at Google), I’ve decided to experiment with enabling comments on this site.
I’m not sure I’ll keep it around, but it’s been a fun project, so I thought I’d record some thoughts on my goals and the technical and design decisions I made along the way in case anyone else using a static site generator is looking for inspiration on how to add comments to their own site.
Since reviving this blog a bit, I’ve gotten a lot of valuable feedback, particularly on the Cynical PM Framework, and had some great discussions with really thoughtful PMs.
My goal is to lower the friction for that discussion and to nudge it into public to encourage more folks to participate.
Second, I wanted the experience to be simple and responsive, not requiring 3rd-party authentication or user account creation of any form. I wanted it to look simple, to perfectly (not just mostly) nestle into the design of this site. And I didn’t want it to have a meaningful impact on page load speed, which is a priority for me, and which I take pride in.
Finally, because I want to keep the quality of discussion high, I wanted a degree of moderation capability, if not some flavor of spam filtering built in.
Static-site native vs. externally hosted
From the outset, I knew I had a critical decision to make. Since this site is built with Lektor, the commenting system needed to play nice with a static site generator.
Despite really wanting to try my hand at a static site-native solution (I’ve been having a lot of fun building Lektor plugins), I ended up selecting the latter category because I could see a clearer path to a finished product sooner. My goals, this time around at least, did not include learning new ways of building software. I just wanted to ship something.
Externally hosted options
Before writing a commenting system myself, I had a mild preference to find something awesome off the shelf. Spoiler: I did not, but I did evaluate two options. Here’s what I found.
Lektor’s official Disqus Plugin was highly tempting. Disqus is well-known and familiar, even among non-tech folk, its UI is reasonably clean, and it would’ve been trivial to install. It also has built-in spam filtering and a polished moderation dashboard.
But Disqus is not made for tiny, independent, privacy-focused websites. Disqus’ customers are large publishers who want to “Monetize engagement” and “Engage their audience.” Trackers do not respect the privacy of my readers and they slow down my site. Disqus was a no-go.
I hadn’t previously heard of Hyvor Talk but checked it out after reading about it, among other commenting options, on Average Linux User.
Hyvor Talk checks the privacy box, is highly fully-featured (I love the Rections feature), and has a reasonably (although not completely) customizable UI. It costs $12/month, which wasn’t a dealbreaker. In fact, $12/month is the cost of a small Heroku app. (This may be foreshadowing.) I don’t love that it requires users to log in to use most of its interesting features.
The more I investigated various options, the more I realized I’d have the most fun and deliver the best solution by building something myself rather than wrangling some existing solution, hosted or not, into the shape I wanted.
How it works
Basic comment operations work simply: submissions and fetches include the post’s path as a key. (This post’s key, for example, is
New comments aren’t publicly visible right away — they go into a moderation queue. Initially, this raised an interesting design problem: because I’m not requiring commenters to log in, if a commenter refreshes the page, their comment apparently disappears into the ether. I wanted to make sure that, as long as they came back using the same browser, they’d still see their pending comment.
To solve this, after the comment is submitted, the comment system sends a randomly generated ID back to the browser, stored in localStorage, that the frontend can use on subsequent requests to get unapproved comments for a given post.
Everything’s hosted in Heroku, for which I pay $12/month. I think I’d prefer it to be a bit cheaper, but I can stand the cost if it means I don’t have to get a certification in DevOps to keep this thing running.
Although the comment system does support moderation, I expect the spam bots to eventually catch on and begin bombarding the form, which is not yet rate limited, with requests.
All CAPTCHAs are terrible, so I’ve been reading a bit about various spam-filtering options on the backend, and Akismet, a pay-what-you-can service, looks reasonably simple to integrate.
I also really like Hyvor Talk’s reactions feature, which is a more sophisticated version of the “Wave” feature I used to have on this blog. I can imagine adding something like that but have some thinking to do about how to support it without requiring visitors to log in.
With that, all that’s left is for you, dear reader, to comment! Looking forward to hearing from you.