Using GitHub Issues for Blog Comments

By Orta Therox

I’ve worked on a few large-scale OSS projects, and I believe that people find it easier to just leave a comment and rely on a contributor to explain a problem rather than consulting the documentation. I consider doing everything you can to make people find their own answers a strong part of defensive open source.

For the posts I write, I have an even lower tolerance for comments. For example, I added the ability to turn off comments per-post and haven’t allowed comments on any posts I’ve written here. A lot of transitory discussion around an article happens on twitter via @ArtsyOpenSource.

I’m willing to give it another shot though, and so I got around to creating a simple system for allowing opt-in comments on posts using GitHub Issues. The rest of this post will be about how you can do it also, and a bit about why I think GitHub Issues are a happy medium for the comments.

orta commented 2 days ago

Comments can be worth a shot.

With a static site like ours it can be a bit tricky, but with an external server and some simple JavaScript it can work out 👍.

Getting set up

The general concept is that you have some JavaScript in your page which requests a list of comments from GitHub. These are available as a JSON API, you can grab that then style the results. Sounds easy right?

Turns out to be a bit more complicated. GitHub’s API has rate-limits for IP addresses, and they’re reasonably low. So, you’ll want to use authenticated requests, but you don’t really want to include your access tokens inside the JavaScript on your blog.

I’ve worked around this with a project called gh-commentify, a node app whose job is to wrap your comment API requests with an access token. You can create your own instance on heroku using this link. It gets scoped to a single org/user, so you can avoid others using your heroku instance for their blog.

From there you need to be able to declare in a post what issue it is hooked up to. This blog uses Jekyll, which has YAML Front Matter on posts. So, I edited our post templates to look for a key comment_id.

From there you need to grab the comments JSON, and move them into the DOM.

I based my work on these two posts:

However this version is more reliable (GitHub authenticated requests) and has fewer dependencies (no jQuery for example).

{% if page.comment_id %}
  <article class='post'>
    {% include gh_comments.html %}
  </article>
{% endif %}

This then imports the required JavaScript into the page. It feels a lot like this:

var writeToComment = function(element, html) {
  var element = document.createElement(element)
  element.innerHTML = html
  document.getElementById("comments").appendChild(element)
}

var loadComments = function(data) {
  writeToComment("h2", "Comments")
  
  for (var i = 0; i < data.length; i++) {
    var commentHTML = [...]
    writeToComment("div", commentHTML)
  }

  var callToAction = [...]
  writeToComment("div", callToAction)
}

var writeFirstComment = function() {
  var callToAction = [...]
  writeToComment("div", callToAction)
}

// This is mostly there now: http://caniuse.com/#feat=fetch
if (window.fetch) {
  var url =
    "https://artsy-blog-gh-commentify.herokuapp.com/repos/artsy/artsy.github.io/issues/{{ page.comment_id }}/comments"

  window
    .fetch(url, { Accept: "application/vnd.github.v3.html+json" })
    .then(function(response) {
      return response.json()
    })
    .then(function(json) {
      if(json.length) {
        loadComments(json)
      } else {
        writeFirstComment()
      }
    })
}

No-one is going to award this JavaScript with a prize for elegance, but it works just fine. That’s basically it, you can edit the DOM however you want.

The full PR for these changes is here: artsy.github.io#363 - and you can see the current HTML/JS here.

Styling

The style of our comments are built to evoke the GitHub UI for issues. This is done to prime people for a relatively different type of comment creation, but still feel like it’s a part of the Artsy OSS style.

orta commented 10 days ago

This is done and dusted.

Why GitHub?

It’s easier for you to keep track of the conversations, you’re likely already having a lot of conversations in a place like GitHub. This means you can use the same flow and tools as your daily job, not relying on a third party service’s emails.

You have good admin tools: you can edit comments, block and report problematic users. These are tools that you have for all repos.

People will be using their developer accounts, which I’d like to hope they will take pride in. You’re probably more likely to get high quality responses. The lack of threading is a bit of a shame in this context, but we’ve lived with it in GitHub Issues for this long, so I’m OK with this.

This setup makes it trivial to drop comments from the blog anytime, and you still have all the comments around in a constructive way after. We don’t have to hope that other services have export features and open data. Everything public is open data on GitHub.

So: low maintenance, works on static sites, data isn’t silo-ed and it’s more likely to result in positive interactions.