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.

In the end — I didn’t end up using the comments implementation, but more on that later…
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:

  1. 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
  2. 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 👇

Screenshots of comments

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-04-05, with message: Tag cleanup.