Shadow Hat
A New Blog

Using GitHub as Commenting Platform

Integrate Utterances' GitHub Issue Commenting to Hexo

If you run a blog, it is always advisable to integrate a commenting system, in order to get feedback on your posts from your readers.

So did I, when I start this blog and I decided to use the Disqus platform, as it was very easy to integrate … but I always had a bad feeling about a third-party platform collecting data from my readers. Disqus is probably not without reason under criticism by many people in the community.

As I host this blog at GitHub (see A New Blog (Part One): VS Code, Hexo and GitHub Pages) I was looking for a solution to host the comments also on my prefered platform. There were some solutions, which uses GitHub Issues for this and wanted to implement something like that someday.

As I read a post from on Thomas Lavesques’ blog, to solve another problem, his commenting section came to my attention: … exactly the solution I needed! Thanx guys…

On their website is a small configurator for a script to implement in each post, which needs only few information:

  • Name of the Repo
  • How the mapping of the post to the Issues should work
  • Name of the Theme, in order to fit to the colors of the blog

The script had to be included to my Hexo article.js:

<% if (!index && post.comments){ %>
  <script src=""
<% } %>

That’s pretty much it. On entering the first comment, Utterances told me to install the needed GitHub App to my repo, in order to make it work … and done.

Utterances GitHub App

The result you see below …


The utterances script tag has the attribute theme, to tell utterances which style should be delivered. There are several themes available, but if users are able to switch between light or dark mode on the page (see Hexo and the Dark Mode), the comment block should change to an suitable theme also.

On order to respond on a mode change, it is necessary to write a more dynamic script loading.

First we define a function in a global script file to load the utterances script via JS:

function insertUtterancesCommentBlock() {
    var commentTheme = "github-light";
    if(localStorage.getItem("theme") === "dark"){
      commentTheme = "github-dark";
    const scriptId = "comment-theme-script";
    const existingScript = document.getElementById(scriptId);
    if (!existingScript) {
      const commentScript = document.createElement("script"); = scriptId;
      commentScript.src = "";
      commentScript.setAttribute("repo", "kristofzerbe/");
      commentScript.setAttribute("issue-term", "pathname");
      commentScript.setAttribute("theme", commentTheme);
      commentScript.setAttribute("crossorigin", "anonymous");
      const placeholder = document.getElementById("comment-placeholder");
      placeholder.innerHTML = "";

Then we change the placement in the EJS file, by defining a placeholder and ensuring that the script above is loaded, before we call it:

<div id="comment-placeholder"></div>
  window.addEventListener('load', function () {

On my blog, everytime the user switches between light/dark mode the body tag will be decorated with the data tag data-theme and the value of the mode. To keep the loading of the utterances script independent from this functionality, we just have to listen to this change via MutationObserver:

//observe theme change, to adjust comment block theme
var target = document.documentElement,
    observer = new MutationObserver(function(mutations) {
        mutations.forEach(function(mutation) {
            if (mutation.attributionName === "data-theme" );
    config = { attributes: true };
observer.observe(target, config);

You can interact with this article (applause, criticism, whatever) by mention it in one of your posts, which will be shown here as a Webmention.

In case your blog software can't send Webmentions, you can use this form or send it manually via or Telegraph:


No Webmentions yet...