Using GitHub to host blog comments: a working example


Up until recently, I was using Disqus as my blog comment system. I never really liked it much though; it was convenient, but I prefer to have all of my blog in one place (i.e. on GitHub). I recently came across this blog, which provides instructions on how to query GitHub issues and load them into a page. It might not be the right solution for everyone—you need a GitHub account to comment on issues, which some would-be commenters might not have—but it seemed perfect for me. I excitedly copied the code into my repository, disabled Disqus, and committed the changes (since I haven’t set up Ruby or a Jekyll environment on computer, all of my testing happens live).

Of course, things rarely work out of the box. A quick recheck of the blog post revealed it was written back in 2011, and things have, um, changed a bit in the last six years. The basic procedure still works, but I’ll re-explain the process with my updates.

The first two steps are the same: you need to manually create an issue in your blog repository’s issue tracker for each blog post you publish, and you need to add the issue number to your post’s YAML front matter. To give you some examples, here is the issue I created for this post, and here is the markdown file of this post with the issue number included in the front matter.

Here’s where things start to change. You need to create a template for the comments section of your post, which I put in my includes folder. I then added a flag to my post layout to include the comments template if an issue number is specified in the post front-matter (I also added a site-level flag in case I want to disable the system in the future). Within the comments template, you need to use Javascript to pull the issue comments using the GitHub API. However, the API has changed significantly, so I had to modify the script to use the right element names. Also, apparently datejs went extinct some time ago, so I substituted the standard Javascript date functionality. I’ve included the code below, with extra white space and line breaks to make it more readable.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script type="text/javascript">
  function loadComments(data) {
    for (var i=0; i<data.length; i++) {
      var cuser = data[i].user.login;
      var cuserlink = data[i].user.html_url;
      var clink = data[i].html_url;
      var cbody = data[i].body_html;
      var cavatarlink = data[i].user.avatar_url;      
      var cdate = new Date(data[i].created_at);
      $("#comments").append(
         "<div class='comment'>" + 
            "<div class='commentheader'>" + 
              "<div class='commentgravatar'>" + 
                '<img src="' + cavatarlink + '" alt="" width="30" height="30">' + 
              "</div>" + 
              "<a class='commentuser' href=\""+ cuserlink + "\">" + 
                cuser + 
              "</a>" + 
              "<a class='commentdate' href=\"" + clink + "\">" + 
                cdate.toLocaleDateString("en") +  
              "</a>" +
            "</div>" + 
            "<div class='commentbody'>" + 
              cbody + 
            "</div>" + 
          "</div>"
      );
    }
  }
  $.ajax("https://api.github.com/repos/mkoohafkan/mkoohafkan.github.io/issues/23/comments", {
    headers: {Accept: "application/vnd.github.v3.html+json"},
    dataType: "json",
    success: function(msg){
      loadComments(msg);
   }
  });
</script>

The headers specification is important. You can request the comment in either markdown format or html format depending on the media type you request. In my case, I’m pulling the comments into an html file, so I request the html media type and extract the body_html element.

You can see the template complete with Javascript code here. Note that you also need JQuery for this work (as shown in the code sample above); my blog already loads JQuery because I use flexslider, so I just modified my head template to load JQuery if either flexslider is used or an issue number is specified (in fact, flexslider broke when I thought I didn’t care about loading JQuery twice).

The other blog then goes into instructions on how enable CORS for a GitHub-hosted blog, and how to register and OAuth application for your blog. I did this when I was still trying to get things working, but you don’t actually need to do this anymore.

Finally, add some css styling to make your comments look good. The css provided by the original blog does work right out of the box, but I used my existing SASS styles to match my blog theme better.

You can see the results below! In the future, I’m planning to extend this system to use comment reactions to moderate which comments get published to the blog. However, the reactions API is still in preview mode, so I’m not going to try anything until it stabilizes.


Comments