Static comments with Hugo, Netlify and … nothing really more

Eric Stemmler

2023/04/14

Zero-Dependency Commenting System

There are seemingly many ways to get comments onto your website. I found most of them either data privacy adverse, bloating or simply too expensive for a small blog. This post describes how to implement a commenting system without additional dependencies for the mentioned setup, that is Hugo + Netlify. The page you’re looking at uses it.

What you need

  1. HTML form for submission of comments
  2. Linux shell script (see below)

How it works

  1. The user submitts a comment via the HTML Form
  2. Netlify Forms collect submissions automatically
  3. A submission triggers a build hook
  4. Netlify starts a Docker container to build the site
  5. The container runs the provided shell script that
    • … downloads and copies all comment submissions into the container and
    • … calls hugo to build the pages, a special comments.html partial reads the comments data to include them into the final page

Most of the code for this post comes from here. So, I wont repeat myself. The depency on JavaScript library Gulp can be substituted in favor of curl and jq Linux command line tools, both already included in Netlify’s build image via a shell script. When I first, went by Tom’s approach, I found that one of the depdencies of Gulp i.e., request is no longer maintained and npm informed me that there were 6 vulnerabilities, for which to fix introduces breaking changes. Great.

In case you are familiar with how Netlify (forms, environment variables, build hook) and Hugo (layouts, partials) works you may skip ahead to the script. Otherwise, I recommend to go through Tom’s post first.

Note that this is very simplistic. You can extend the setup to enable notification, approval and deletion of posts.

Update: https://commentbox.io/ has added a generous free-tier option and claims to be tracking-free.

Shell Script (curl + jq + hugo)

#!/bin/sh

# create output file path
odir=`dirname $0`
ofile="${odir}/data/comments.json"

# create directory "data" if it doesn't exist
if [ ! -d "data" ]
then
	mkdir data
fi

# set local variables if building locally
# otherwise the necessary variables should
# be setup via Netlify and present in the Docker container
if [ -e ".env" ]
then
	echo "environment variable file found"
	. ./.env
fi

# get all comments
curl https://api.netlify.com/api/v1/forms/${COMMENT_FORM_ID}/submissions/?access_token=${API_AUTH} |

# pull out relevant data
jq '{null: map({name: .name, comment: .body, date: .created_at, path: .data.path})}' > "$ofile"

# build 
hugo

This script downloads all submissions from Netlify’s API. There is going to be additional data in the resulting JSON file. The jq command is a JSON filtering tool, that outputs only what we need into a file named data/comments.json.

You need to have an API token and the form ID for this. Since those should be known only to you, you should not commit them to your repository. Instead, create two environment variables in your Netlify account to make them securly available to the script at runtime. If you want to build and test your site locally, you can create a file .env like this

COMMENT_FORM_ID=abcdefg123456789
API_AUTH=abcdefghijklmnopqrstuvwxyz1234567890

The shell script checks whether file .env is present and if so, loads it. Finally, specify the build command in you netlify.toml config file.

[build]
command = "./get-comments-and-build.sh"
...

Comments

Your email address will not be published
Jack on Thu, 01 Feb. 2024, 12:17 UTC

Nice! I have been looking for this, too!