When moving my website back from MediaWiki to Hugo — I again started to think about adding comments. I’ve thought about this before, even tested quite a bit, and written about it.
I didn’t want to add heavy external resources, or compromise my readers privacy. This blog is static, and I’d like the comments to be static as well.
Table of contents
The Github API
There are a few services out there, like utterances, that uses Github issues as a basis for comments. I like the idea, but I didn’t want to include any external scripts.
Instead I used the Github API as a data source, statically generating the comments.
- Pros
- The comments become part of the site
- No external scripts or styling required
- Super fast loading
- Cons
- The comments are not live
- Users must navigate to Github to leave comments
- Site must periodically rebuilt to include new comments
There are two ways, that I can think of, to get the comment data from the Github API:
-
Add the Github API endpoint as a data source
- There is no way to authenticate with this solution, so the rate limiting is much stricter
- Comment data is fetched during the build, and is not part of the repo
-
Periodically pull the Github API with a script
- This can be done as an authenticated user, meaning you have a lot higher rate limits
- The comment data can be stored as json files in the
data
folder, and committed to the repository
Getting the comments
I chose option 2 and made a tiny bash script:
cd ~/cavelab-blog/data/comments
git pull
for issue in {1..100}
do
wget \
--header "Accept: application/vnd.github.v3+json" \
--header "Authorization: token xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
--server-response \
"https://api.github.com/repos/thomasjsn/blog-comments/issues/$issue/comments" -O $issue.json || break
sleep 3
done
# delete any empty json files
find . -type f -empty -delete
git add .
git commit -m 'fetched comments from github'
git push
This script tries to fetch issue IDs 1 to 100 — if an error is returned, like 404, it stops. Since the issue IDs are incremental numbers, and usually not deleted, this simple solution works quite well.
The result of the script are json files with the issue ID, like 1.json
for issue ID 1. These files are placed inside the data/comments
folder; added and committed to git. That triggers a Drone build, which then builds and deploys the site, with the comments 😃
Displaying the comments
Now to display the comments — I used a front matter parameter for the issue ID:
commentIssueId = 1
In the single template file I added a section to include the comments.html
partial, if the front matter had the commentIssueId
parameter.
{{ if (isset .Params "commentissueid") }}
<div class="post-comments">
{{ partial "comments.html" . }}
</div>
{{ end }}
And then the partial template, for iterating and showing the comments:
{{- $id := .Params.CommentIssueId -}}
<h3>
Join the discussion on
<a href="https://github.com/thomasjsn/blog-comments/issues/{{ $id }}#new_comment_field" target="_blank">GitHub</a>
</h3>
{{ with $.Site.Data.comments }}
<dl>
{{ range (index . (string $id)) }}
<dt>
<a href="{{.user.html_url}}" target="_blank" style="font-weight: bold">{{.user.login}}</a>
{{ if eq .author_association "OWNER" }}
<code>root</code>
{{ end }}
—
<a href="{{.html_url}}" target="_blank">{{dateFormat "2006-01-02" .created_at }}</a>
</dt>
<dd>
{{ $markdown := .body | markdownify }}
{{ if not ( strings.Contains $markdown "<p>" ) }}
<p>{{ $markdown | emojify }}</p>
{{ else }}
{{ $markdown | emojify }}
{{ end }}
</dd>
{{ end }}
</dl>
{{ end }}
And this was the result 👇
The “Join the discussion on Github” link takes users directly to the new comment field on the issue ID specified in the front matter.
Comments are markdown formatted, just as on Github. Emojis even worked 😃 I added a root
badge if the comment was written by the repository owner, aka. me.
Why not?
I liked the solution, but I ended up not using it — why?
Well, I tried it on a post that got about 1000 visitors after being posted in Reddit. But not a single comment… I just figured it wasn’t worth the extra hassle. Even though the solution is quite simple and elegant, it does require a scheduled task to get the comments. And for me to manually create the issues and add the issue ID to the post front matter.
Feedback and communication often happens on other platforms, where I share some of my posts, like Twitter and Reddit.
Instead I added a “Feedback and correction” link to the bottom of all pages, with a simple mailto link. I got that idea from Ctrl blog, thanks Daniel 👍
Last commit 2024-11-11, with message: Add lots of tags to posts.