Discourse Commenting for Jekyll

Oct 21, 2016
Joe Buhlig
~3 mins

For years, Disqus has been the commenting platform of choice. It’s what I used when my site was on WordPress. When I switched to a static site generated by Jekyll, I pulled commenting entirely. But given the topics I write about, comments can be quite helpful and I realize that was a mistake. So I brought them back with the help of Discourse.

There are a number of reasons I chose Discourse, but suffice it to say that I just like it better than the alternatives, which are actually few in number for static sites. I have a unique way of doing the embed process that I thought other Jekyll users might find helpful.

The Discourse Side

Assuming you have an instance of Discourse running (not the purpose of this post) and you are an admin on said instance, you add the host site as an allowed host in the Discourse settings (Customize → Embedding). That will generate the code you need to embed on each page you want commenting enabled. You’ll have to change the embed URL within the code to match the canonical URL of the page it’s embedded on. This is what it looks like originally:

<div id='discourse-comments'></div>
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'http://discussion.joebuhlig.com/',
                     discourseEmbedUrl: 'REPLACE_ME' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

The Jekyll Side

This can’t get more basic. Paste the code from Discourse to the bottom of the post layout in Jekyll. After I make the edit for the embed URL, this is what the code looks like:

<div id='discourse-comments'></div>
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'http://discussion.joebuhlig.com/',
                     discourseEmbedUrl: '{{site.url}}{{page.url}}' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>

Development Tweaks

Every change I make to the site is previewed before deployment. Each post is reviewed as well. So it’s quite normal for me to run jekyll s --future. But I don’t want any issues with the embed code when I’m in my development environment, so I tell Jekyll to only add the embed code when the site is being created for production:

{% if jekyll.environment == "production" %}
<div id='discourse-comments'></div>
<script type="text/javascript">
  DiscourseEmbed = { discourseUrl: 'http://discussion.joebuhlig.com/',
                     discourseEmbedUrl: '{{site.url}}{{page.url}}' };

  (function() {
    var d = document.createElement('script'); d.type = 'text/javascript'; d.async = true;
    d.src = DiscourseEmbed.discourseUrl + 'javascripts/embed.js';
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(d);
  })();
</script>
{% endif %}

Now when I’m ready to deploy my changes I run JEKYLL_ENV=production jekyll b. That sets the environment variable to production instead of development and means the embed code is only included when I’m building the site for real. I use the same trick for my Piwik tracking code. It keeps my external dependencies from creating issues while I am developing.