Revamping 1klb comments part one: an overview

Published
8 March 2021
Tagged
Part of a series: Revamping 1klb comments

A little while back I created a commenting system for this blog. The blog itself is served via a static site generator (specifically nanoc served on netlify), so a commenting system isn't as simple as putting an html form in the page and hooking it up to a database on the server. Instead, I ended up using a hybrid of netlify's forms, the web-based database system Fauna DB, and some javascript.

But the issue was that this system didn't really work that well. Comments got lost in the churn, I got notified kind of poorly, and it was all a bit messy. So a month or so back I completely revamped the commenting system, cutting out the middle-man (in this case Netlify forms), adding some moderation features, improving notifications, and generally making it run smoother.

The end product takes a bit more effort to put into production, but I think it's worth showing off. In this first post, I'll do a big picture overview of the whole system.

The big plan

So how will all of this work? The big picture is as follows:

Comments are stored in Fauna. Fauna is a web-based database, accessible both via its own custom API (which you usually access through a custom library) or through GraphQL, a kind of web-optimised query language. To be honest the choice of database doesn't matter too much, as long as it's accessible via the web and allows minimal server-side checking and logic. As well as storing data on Fauna, we'll be using stored functions in the database to run some server-side logic and pass off processing to the place where it's best done - next to the data.

Readers access blog post comments via javascript. Specifically, javascript in the blog post itself will fetch the comments from the Fauna database and display them on the web page. This means that you will need javascript enabled to view blog comments - there's no way around this, really.[1]

Readers can submit comments to a server-side function. The server-side function, hosted and run by Netlify, will then scan the comment to ensure it's not spam (although don't expect any super-advanced spam detection technology) and then fire a request to the Fauna database to create a new comment. That same server-side function will then email the blog admin (i.e. me) letting them know that someone has made a comment. By default, we can ensure that comments are held pending approval. This means that even if spam-bots can be bothered commenting on a very out-of-the-way blog, and get past my definitely very advanced spam-prevention technology, I won't get flooded with ads for package holidays or knock-off Air Jordans or whatever it is that spam bots advertise these days.

I log on to the admin panel on this website and approve comments. The admin panel is all done in javascript - quite a cool trick that I'm keen to show off. Everything is javascript: the login function, the comment listings, the moderation. And (somehow, incredibly) the whole thing is secure enough that even if you went to the admin panel and downloaded all the source code, you shouldn't be able to randomly approve/deny comments. No security through obscurity here!

Once approved, the comment is available to view on the main site. We're back to step one!

So what's first?

In my next post[2], I'll explore how we set up that Netlify database. We'll talk about object and database design, indices and functions, and how we can set up a nice GraphQL interface for efficient comment fetching.

In the meantime: if you're interested to hear about a specific section of this process, let me know via the comments below!


  1. Technically, you can build a trigger that will re-build your entire website, embedding comments into the webpage, every time a comment is created or updated. But I think this is a bit brute-force. ↩︎

  2. Keeping these blog posts bite-sized means that there's less for you to read, and also that it's much easier for me to actually write them. Otherwise I'd be writing a post the length of War and Peace that would also take four months to complete. ↩︎