Adding comments to a Jekyll site with Staticman

Offloading comments to an third party service like Disqus1 has always felt like a necessary evil to me when building static Jekyll sites.

Convenient to embed a small bit of <script> voodoo from them into your pages — sure. But kiss goodbye to controlling the user experience, look and feel, site performance, data, and your privacy. Disqus alternatives haven’t been all that great for the statically-minded unless you were willing to make some compromises…

In this tutorial follow my journey as I explore the possible ways of adding commenting to a Jekyll static site. Eventually working towards a setup that could statically generate comments from files not at all different from those already consumed by Jekyll for posts and pages.

Self hosted comment systems

Isso describes itself as “commenting software similar to Disqus.” You host a SQLite database and embed some JavaScript on your pages (just like Disqus and friends) and you’re ready to roll. After freeing my content from Wordpress and “going static” I really didn’t want to manage a server and database again just to have comments on my site. So these solutions were out.

Other self-hosted commenting systems include: Commento, Remark42, Discourse, talkatv, Juvia, HashOver, and Savas.

GitHub based comments

If you’re against using a 3rd party or spinning up your own server. The thought of leveraging GitHub’s API for commenting may appeal to you. utterances and giscus are two open source projects that rely on GitHub issues and discussions to store comments.

Connect their respective app to your GitHub repository, configure how posts are mapped to issues/discussions, set a theme, add lightweight JavaScript to your site, and you’re done.

Both are ideal solutions for sites with an audience that skews towards developers and may already have a GitHub account. I want something platform agnostic and didn’t require any sort of account to leave a comment… so the search continued.

Static comments

What I really was searching for was a commenting system to compliment the rest of my statically generated Jekyll site.

Over the years I’ve come across several solutions that seemed promising:

  • Use mailto links (how very retro) to email comments to yourself to then manipulate and add directly to a post.
  • Use PHP to do something similar.

Jekyll plugins like Jekyll::StaticComments and Jekyll AWS Comments were pretty close to what I was looking for. A PHP <form> captures a comment, converts into YAML and emails it over to be placed in a prescribed location. Then with the help of a Liquid for loop, comments are displayed on the appropriate pages.

I can’t really explain it, but something about using PHP in combination with Jekyll felt off to me. And so I didn’t pull the trigger on these solutions either.

It wasn’t until I discovered Eduardo Bouças’s blog post “Rethinking the Comment System for My Jekyll Site” and the launch of Staticman 2.0 that I finally decided to remove Disqus from my site.

And with that, started the process of migrating years of comment data and integrating them into the rest of my statically built site.

Enter Staticman

On paper and in practice Staticman was the app I was looking for to power static-based commenting on my site.

  • Designed to work with Jekyll and GitHub Pages.
  • Free and open source. Run it on your own server as a Node.js app or go the free hosted route with Heroku.
  • Complete control over the data, content, user experience, and user interface.
  • Not just for comments! Perfect for any sort of user generated content: reviews, comments, polls, and more.
  • User submitted content can be merged in automatically or moderated.

Getting started

Much like building my first Jekyll site, I found the process of integrating Staticman into my workflow very rewarding. It was nice to get dirty again crafting form markup and styling comments to fit in with the rest of my site.

Thankfully I didn’t have to start from scratch as I was able to draw inspiration from the Staticman demo site — Popcorn and Eduardo Bouças’s personal site. The documentation for Staticman does a good job of explaining how to set things up so definitely give that a read first to familiarize yourself with what the app can do.

Building the form

I set my gaze on marking up the “Leave a comment” submission form first. Seemed like an easy target as the styling of various form elements like <input>, <label>, <textarea> and buttons were already done as part of my living style guide.

To complete it, was to make a decision on what fields I wanted to capture, and write a little bit of JavaScript for form handling and submission. Arriving at this for my post__comments.html include (class names and Liquid removed for brevity).

<form id="comment-form" method="post" action="{{ site.staticman.endpoint }}{{ site.repository }}/{{ site.staticman.branch }}">
  <fieldset>
    <label for="comment-form-message">Comment</label>
    <textarea type="text" rows="3" id="comment-form-message" name="fields[message]"></textarea>
  </fieldset>
  <fieldset>
    <label for="comment-form-name">Name</label>
    <input type="text" id="comment-form-name" name="fields[name]"/>
  </fieldset>
  <fieldset>
    <label for="comment-form-email">Email address</label>
    <input type="email" id="comment-form-email" name="fields[email]"/>
  </fieldset>
  <fieldset>
    <label for="comment-form-url">Website</label>
    <input type="url" id="comment-form-url" name="fields[url]"/>
  </fieldset>
  <fieldset class="hidden" style="display: none;">
    <!-- used by Staticman to generate filenames for each comment -->
    <input type="hidden" name="options[slug]" value="{{ page.slug }}">
    <!-- honey pot used to filter out spam -->
    <label for="comment-form-location">Not used. Leave blank if you are a human.</label>
    <input type="text" id="comment-form-location" name="fields[hidden]" autocomplete="off"/>
  </fieldset>
  <fieldset>
    <button type="submit" id="comment-form-submit">Submit Comment</button>
  </fieldset>
</form>
<!-- End new comment form -->

Staticman’s documentation covers this in more detail, but essentially I’m adding fields[] values to the name attributes. message, name, email, and url fields are then used to generate a .yml file similar to this:

message: "![Bill Murray](http://www.fillmurray.com/400/300)\r\n\r\n“It's hard to be an artist. It's hard to be anything. It's hard to be.”"
name: Bill Murray
email: b0caa2a71f5066b3d90711c224578c21
website: ''
hidden: ''
date: '2016-08-11T19:33:25.928Z'

Some notes on the hidden and date fields you may have noticed in the sample comment above:

Hidden: is used as a spam deterrent in the form of a honeypot. The thought is a human wouldn’t fill out an input they can’t see, but a spam bot may. Adding fields[hidden] to this input and not placing it in the allowedFields array in our Jekyll config, instructs Staticman to reject the entry. Hopefully filtering out bots who are dumb enough to populate it with something.

Date: is captured when the entry is generated by Staticman. Its format can be changed from iso8601 (default) to timestamp-seconds or timestamp-milliseconds.

Interactions and state

Using Popcorn’s main.js as a guide I added all the AJAX goodness, alert messaging, along with disabled and loading form states.

To avoid disrupting the flow too much I went with inline alert messaging directly above the submit button.

Inline comment form alert example

And to improve the user experience upon submission the submit button’s text changes to Loading..., becomes disabled, and an animated SVG icon inserted for bit of extra flare.

$(form).addClass('disabled');
$('#comment-form-submit').html('<svg class="icon spin"><use xlink:href="#icon-loading"></use></svg> Loading...');
Submit button loading animation.

If the form is successfully submitted a message appears notifying the user that the comment has been received and is pending moderation. Since my site takes a bit to generate with Jekyll I felt it necessary to convey this to the user, hopefully avoiding duplicate submissions.

With smaller sites hosted with GitHub Pages this becomes less of a problem — as they build much faster. Especially true if you decide to go with the auto merge option and skip moderating comments.

Form submit success animation.

Displaying comments

There’s a bunch of Staticman settings available to you, but forget all that for right now. The important bit to remember is: static comment files will live in _data/comments/<post slug>/. By predictably placing them here we will be able to access their contents from the following array: site.data.comments[page.slug].

With this array we’ll be looping through it with for just like you would with site.posts to spit out a list of all posts. But first we’ll use an assign tag to rename the array and apply a sort2 filter on the objects. This will order them by filename, which in our case should be chronological3.

{% assign comments = site.data.comments[page.slug] | sort %}
{% for comment in comments %}
  show a comment
{% endfor %}

Since I’m capturing message, name, email, and url in the comment form these will be the same fields I’ll want to pull from to build each comment. Using an assign tag again we’ll cleanup variable names like comment[1].avatar into just avatar. Which will then be used to pass parameters into the comment.html include:

{% assign comments = site.data.comments[page.slug] | sort %}
{% for comment in comments %}
  {% assign avatar = comment[1].avatar %}
  {% assign email = comment[1].email %}
  {% assign name = comment[1].name %}
  {% assign url = comment[1].url %}
  {% assign date = comment[1].date %}
  {% assign message = comment[1].message %}
  {% include comment.html index=forloop.index avatar=avatar email=email name=name url=url date=date message=message %}
{% endfor %}

If done correctly the values and strings in a data file like _data/comments/basics/comment-2014-02-10-040840.yml

---
id: comment-1237690364
date: '2014-02-10 04:08:40 +0000'
updated: '2014-02-10 04:08:40 +0000'
post_id: "/basics"
name: Tamara
website: ''
message: "This? This is freakin' awesome! Thanks so much for sharing your mad skills and expertise with us!"

Should pass through _includes/comment.html and spit out as the following HTML:

<article id="comment1" class="js-comment comment" itemprop="comment" itemscope itemtype="http://schema.org/Comment">
  <div class="comment__avatar-wrapper">
    <img class="comment__avatar" src="https://www.gravatar.com/avatar/?d=mm&amp;s=50" srcset="https://www.gravatar.com/avatar/?d=mm&amp;s=100 2x" alt="Tamara" height="50" width="50">
  </div>
  <div class="comment__content-wrapper">
    <h3 class="comment__author" itemprop="author" itemscope itemtype="http://schema.org/Person">
      <span itemprop="name">Tamara</span>
    </h3>
    <div class="comment__date">
      <a href="#comment1" itemprop="url">
      <time datetime="2014-02-09T23:08:40-05:00" itemprop="datePublished">February 09, 2014 at 11:08 PM</time>
      </a>
    </div>
    <div itemprop="text"><p>This? This is freakin’ awesome! Thanks so much for sharing your mad skills and expertise with us!</p></div>
  </div>
</article>

Looking like this when styled with CSS:

Comment example

There’s not much magic in the comment.html include — some structured data markup sprinkled about and a few Liquid conditionals for displaying author avatars and URLs.

Setting up Staticman

With the front-end portion of my static-based comment system squared away, it was time to configure Staticman. Because I went with the hosted version, it only took a few quick steps to setup.

Adding Staticman as a collaborator

First you need to grant Staticman access to your Jekyll repository on GitHub. You don’t have to actually host the site there (I use Netlify for that), but it does need to be a standard Jekyll site with valid _config.yml.

Following the docs I added GitHub username staticmanapp as a collaborator and then pinged https://api.staticman.net/v1/connect/{your GitHub username}/{your repository name} as instructed to accept the invitation.

staticmanapp as collaborator

Configuring Staticman

Staticman is configured by settings defined in your Jekyll _config.yml under a staticman object. There’s a whole list of stuff you can configure — the important stuff being allowedFields, branch, format, moderation, and path.

There’s also an undocumented generatedFields4 setting that is useful for time stamping each file Staticman creates.

I ended up with the following settings in my _config.yml:

staticman:
  allowedFields     : ['name', 'email', 'url', 'message']
  branch            : "master"
  commitMessage     : "New comment."
  filename          : comment-{@timestamp}
  format            : "yml"
  moderation        : true
  path              : "_data/comments/{options.slug}"
  requiredFields    : ['name', 'email', 'message']
  transforms:
    email           : "md5"
  generatedFields:
    date:
      type          : "date"
      options:
        format      : "iso8601"

In case any spam makes it through, you may like another layer of “protection” to block it. Setting moderation: true will make Staticman send a pull request whenever a new comment entry is submitted. At this point you can examine the content inside of the PR and decide if you want to merge or close it.

When hosting with Netlify, GitHub Pages, and the like — a merge will instantly force Jekyll to rebuild the site and deploy. Since I self host I have the extra step of pulling from remote, before building locally and deploying via rsync.

Hooking up the form

For your forms to work with Staticman they need to POST to:

{Staticman endpoint}{your GitHub repository}/{your repository name}/{the name of the branch}

Instead of hard-coding these values, use site variables defined in the _config.yml file. For example {{ site.repository }} and {{ site.staticman.branch }} respectively.

# sample _config.yml

repository: "mmistakes/made-mistakes-jekyll"
staticman:
  branch: "master"

Hitting the Staticman endpoint should trigger the success and error messages in our comment <form>. Firing up the console in your browser of choice can also give you some more hints on what’s going on if you encounter any snags.

For example if all of the required fields aren’t filled out an error like this could hit the console:

Object {readyState: 4, responseText: "[{"code":"MISSING_REQUIRED_FIELDS","data":["name","email","message"]}]", responseJSON: Array[1], status: 500, statusText: "error"}

Publishing comments

If configured correctly you should receive a pull request notification on GitHub each time a comment entry is submitted. Look the commit over (if you’re moderating them) and merge pull request to accept or close to block it.

Staticman pull request notifications on GitHub

Staticman pull request merge on GitHub


Migrating Disqus comments

It was now time to deal with the 500+ Disqus comments I’ve accumulated. A good chunk of them had valuable content worth keeping, so I didn’t want to ditch them all.

I came across a Rake task by Patrick Hawks, aptly named jekyll-disqus-comments that downloads Disqus posts as YAML files via the Disqus API.

With some modifications I was able to get it working with my Jekyll site and posts files.

Installing

Copy the following files to the root of your Jekyll project folder.

Obtain a Disqus API public key

To use the plugin, you will need to acquire a public key from the Disqus API and add it to your _config.yml. You can do this by:

Step 1. Register new application.

Step 2. Setup application using suggested configuration below:

Label: <Name of application> eg. Jekyll Disqus importer
Description: Convert comments into static files.
Website:
Domains: disqus.com
Default Access: Read only

Step 3. Add the following lines to your _config.yml:

comments:
  disqus:
    short_name: YOUR-DISQUS-FORUM-SHORTNAME-HERE
    api_key: YOUR-DISQUS-PUBLIC-KEY-HERE

Run import task

Import comments from Disqus by running rake disquscomments from the CLI. If it completes without error you should find a set of .yml files in _data/comments/<post-slug>/ similar to this:

├── _data
|  └── comments
|      └── 365-days-of-drawing
|      |   └── comment-2013-08-30-162902.yml
|      |   └── comment-2013-08-30-204505.yml
|      └── basics
|          └── comment-2014-02-10-040840.yml

With each of these files should having front matter data similar to this:

---
id: comment-1237690364
date: '2014-02-10 04:08:40 +0000'
updated: '2014-02-10 04:08:40 +0000'
post_id: "/basics"
name: Tamara
website: ''
message: "This? This is freakin' awesome! Thanks so much for sharing your mad skills and expertise with us!"

Key names correlate with the ones defined earlier with Staticman, along with a few specific to Disqus: id, updated, and post_id that aren’t currently used on the site.

I’m a little obsessive so I went through a ton of old comments adding GitHub Flavored Markdown5 backticks to improve the reading experience of code blocks. Having properly formatted code blocks in comments looks so good I couldn’t pass it up.

Pulling this off with Disqus required way more work and didn’t support Markdown.

Syntax highlighted code blocks in comments

Troubleshooting

When running rake disquscomments I ran into warnings like this:

Comments feed not found: <domain.com>/post-slug/

For posts that I knew didn’t have any comments this wasn’t a problem, but for those that did it was a real head scratcher. Eventually I discovered that ident in disqus_comments.rake wasn’t matching the style of post paths used on my site.

I was able to determine what Disqus was expecting for id’s and adjust the plugin by:

  1. Exporting all my Disqus comments as XML.
  2. Opening the Disqus XML file.
  3. Looking at the <link> elements eg. <link>https://mademistakes.com/mastering-paper/contour-drawing/</link>

By playing around with the following line in disqus_comments.rake I finally sorted it out:

# site.url + post.id + trailing slash
ident = site['url'] + post.id + '/'

Final thoughts

Treating comments as content and integrating them into the same build process as the rest of my site has been an informative and rewarding experience. By successfully migrating over 500 comments away from Disqus I was able to:

  • Style them consistently to match the rest of the site’s design.
  • Improve the appearance of <code> blocks within comments.
  • Make it easier for visitors to leave a comment without having to create a Disqus account.

SEO implications

The comments left on many of my posts often contain corrections, follow-up, and other valuable post content. From earlier tests it did seem as if search engines were able to crawl the embedded Disqus JavaScript comments and partially index them. Time will tell if I’ll see any SEO lift now that comments are part of the HTML and marked up as structured data.

Spam slipping through

Seems to only happen on my older posts or ones that rank well with Google and friends. As no one is really adding valuable comments to these I’ve added a comments_locked conditional to disable the comment form on specific pages.

{% unless page.comments_locked == true %}
  <!-- comment form -->
{% else %}
  <p><!-- comments locked messaging --></p>
{% endunless %}

I’ll have to keep an eye on the effectiveness of this method, or possibly find a tastier honeypot to better combat spam bots.

Comment replies

One thing I miss since leaving Disqus, are comment notifications. Sure you can setup GitHub to notify you of each Staticman pull request, which will in turn clue you in that you have a new comment. What’s missing is a way to notify the commenter that there’s been a reply to their comment.

Less likely a commenter will return to the page to see if a reply was made without the nudge of a notification. Wordpress and friends has the whole “subscribe to comments” feature which could apply here I suppose.


  1. There are several third-party commenting services to choose from: Disqus, IntenseDebate, Facebook, and countless others. They all essentially work the same — you embed someone else’s JavaScript on your site and comments magically appear. ↩︎

  2. Sort an array. Optional arguments for hashes: 1. property name 2. nils order (first or last). ↩︎

  3. eg. comment-2014-02-10-040840.yml, comment-2015-03-22-204128.yml, etc. ↩︎

  4. Adds a date timestamp to entries in ISO8601, seconds, or milliseconds formats. ↩︎

  5. The markdownify filter is used in _includes/comment.html to convert Markdown-formatted strings found in {{ include.message }} into HTML. ↩︎

Tags:

31 comments

  1. Frank Taillandier ·

    This post definitively deserves static comments.

  2. Moritz »mo.« Sauer ·

    Thank you once again to rise the bar for the development of Jekyll themes. Now I want to try this, too. Disqus was – like you wrote – a necessary evil. Staticman looks like the ideal solution.

  3. Michael Rose ·

    It’s pretty darn slick that’s for sure! Hardest part to the whole thing was getting all the Disqus comments converted into .yml files.

  4. Josh Habdas ·

    This is simply fantastic, Michael. Great work! I’m curious to know how the switch to static comments has affected your crawl stats in Google Search Console. If I had to guess you should see more frequent crawling and less time spent downloading, which could carry aggregate benefits not obvious until analyzed over a longer period of time.

    Since you’re looking for alternative static commenting strategies…I stumbled upon jekyll-aws-comments today linked from lambda-comments. It’s probably more complex to get going but ideal for control freaks who don’t want to rely on a 3rd party, and who might already be hosting their Jekyll blogs on AWS with CloudFront for example. Again, great work! Love it!!

  5. Michael Rose ·

    Thanks Josh. I came across those as well in my search but since I don’t have any experience with AWS I passed them over. Definitely seem like good options though, especially if you’re hosting with AWS.

    As far as stats. I launched static comments in mid-August, looking at my crawl stats there isn’t much that jumps out to me. Kilobytes downloaded seems to be trending up but hard to tell.

    Made Mistakes crawl stats

    One thing I’ve noticed is the need for better comment spam filtering. I get around 1-3 submitted comments a day that are clearly spammers trying to get backlinks. Back with Disqus I got zero, so it must have been doing a good job of filtering that junk out.

    Not entirely sure if its bot driven or not but thinking if Staticman adds support for ReCaptcha, that might help combat it.

  6. Arnab Wahid ·

    I have been searching for a decent alternative of Disqus for a few years now. This is the best one so far. Thanks a lot, Michael!

    I was wondering, does Staticman support threaded comments? If not, would I be able to get it by tinkering with the styling?

  7. Michael Rose ·

    @Arnab - I’m sure Staticman could be “bended” to support threaded comments, but it would take some work on your end. Off the top of my head I’d probably do something similar to how Wordpress adds reply links to each comment.

    That could be used to create a variable that references the comment # being replied to. Which you’d send with the rest of the comment data to Staticman, adding it the YAML Front Matter.

    Then in the comment Liquid code you’d add some sort of check for that variable and if present on the current comment, pull in any replies. Probably using something like the where filter.

  8. Hosein ·

    Hey Michael, Great post indeed, However I have some questions:

    1. How would you include pictures in your comments?
    2. I want my pages to have comments too, especially the homepage. But I don’t know what would be my homepage slug.

    With thanks

  9. Michael Rose ·

    Since Markdown is supported you can write something like:

    ![title](https://fakeimg.pl/600x400)
    

    To add images to a comment… they need to be hosted somewhere though since as far as I know Staticman doesn’t deal with uploaded files.

  10. Michael Rose ·

    Also. I’m pretty sure slug is available to both posts and pages. I know for certain it works with collection documents because I use this exact same method to add comments to my FAQ section, which is built using a collection.

    Experiment and try it out. As long as a page has a unique identifier you should be able to pull comment content from a _data file.

  11. Hosein ·

    Thank you Michael. As far as I tried, there was no page slug available for pages. I solved this problem by defining slug as a custom variable for each page.

  12. Duc Nguyen ·

    Thanks Michael. I have a question: how can I add Staticman comments to my blog? I’m using Windows and host my Jekyll on Firebase.

  13. Michael Rose ·

    @Duc - Start by reading this post. The steps I followed to add Staticman are all here. I have no experience with Firebase so I’d be no help there but the Jekyll side of things would be very similar to what I’ve outlined above.

  14. Bozdar ·

    I am revamping my website and moving to Jekyll. I am not sure, if Staticman works in case I am pushing only _site folder to Github?

  15. Michael Rose ·

    @Bozdar - I think it’s doable, just might introduce some complexity to your build/deploy process.

    For example, I don’t use GitHub to build or host my site, but simply store my source files there in a repo. My build/deploy process with Staticman goes like this:

    1. Comment is submitted to Staticman, which creates a pull request against my site repo on GitHub.
    2. Comment pull request is merged and then I pull that commit to my local repo.
    3. Build the site locally.
    4. Deploy the contents of my _site folder to my server. I use a Gulp rsync task but there are several other options available to you.

    All Staticman needs is to be made a collaborator on your repo and be able to see your _config.yml so it can be configured."

  16. Bozdar ·

    Michael. Then, it seems a bit easy but real situation is that I am hosting my website on Github, at least for the time being. So, I do not find Staticman helpful enough because it needs _config.yml file to work. I may use Staticman in future when I change my host.

    Many thanks, for the help.

  17. Dany Keep ·

    Thanks for the awesome theme Minimal Mistakes.

    Unfortunately, I couldn’t configure static comments for my project.

    I receive pull requests on github, but comments not published in my post. https://github.com/danykeep/danykeep.github.io

    Help me please, how can i solve this problem? I tried to turn to false moderation option, but it didn’t help.

  18. Michael Rose ·

    @Dany - Change Staticman’s path in _config.yml. You were probably using the demo site’s path which places the comment data files in a different location. You want it set as:

    staticman:
      path: '/_data/comments/{options.slug}'
    

    Move your existing /comments/ folder under /_data/ after you make the config change and on rebuild they should up.

  19. Michael Rose ·

    Staticman now supports threaded comments. The Liquid you need to craft can get messy, but it’s manageable if you don’t nest too deep.

  20. Arnab Wahid ·

    Thanks for the update. I have been meaning to bother you with a couple of questions but been hesitant about it for obvious reasons. I am still not sure if I should attempt a conversation that will probably never end! However, initially , I am just looking for some advice. But first, let me read your latest post first. I will continue my nervous babbling there.

  21. Chuck ·

    This code has been a terrific help to me for a site I’m working on… but I’m having quite a time trying to sort my comments by the date. {% assign comments = site.data.comments[page.slug] | sort: "date" %} is throwing an error to the effect that there’s no implicit conversion of String into Integer. My filenames aren’t going to be guaranteed sequential, so sorting by those won’t work… any idea what might be going wrong here?

  22. Michael Rose ·

    I had the same problem when trying to sort using the date value. I think the issue is Staticman captures that field as a string since it’s encased in single quotes, causing Liquid to throw an error as it can’t compare strings against integers… or a date timestamp.

    I tried everything I could think of to convert the date values from a string so they could be sorted, but never found a solution. Jekyll has several filters for converting to various date formats and even the to_integer, so I thought if I could capture the array, filter it the date fields, then I’d have an array with date values that I could sort. Never got that working though.

    In the end I threw in the towel and just renamed all my legacy comment _data files so they were sequential using a Unix timestamp, matching the same filename format I defined for Staticman (filename: comment-{@timestamp}).

  23. Nur Andi Setiabudi ·

    I had similar problem with @Dany, and it has been resolved by changing path and /comment/ folder.

    But, now I get another problem that comment cannot be submitted. Error message:

    Sorry, there was an error with your submission. Please make sure all required fields have been completed and try again
    

    Thank you. Repo: https://github.com/nurandi/nurandi.github.io

  24. Michael Rose ·

    @Nur - Likely something is off with your Staticman config. If you open your browser’s web development tools and look at the Console output it will give you a better idea of what data from the form Staticman doesn’t like.

    For example if I try to submit a comment with the name and email fields blank you’ll see this error in the Console.

    Console screenshot

  25. Nur Andi Setiabudi ·

    @Michael - Problem has been resolved by changing:

    staticman:
      path: "/_data/comments/{options.slug}"
    

    To:

    staticman:
      path: "_data/comments/{options.slug}"
    
  26. Nur Andi Setiabudi ·

    @Michael, I get problem when import comment from disqus by running rake disquscomments

    rake disquscomments
    
    rake aborted!
    LoadError: cannot load such file -- domainatrix
    _rake/disqus_comments.rake:5:in `<top (required)>'
    /Users/widyaningsih/Documents/3. Andi/nurandi.github.io/Rakefile:8:in `load'
    /Users/widyaningsih/Documents/3. Andi/nurandi.github.io/Rakefile:8:in `block in <top (required)>'
    /Users/widyaningsih/Documents/3. Andi/nurandi.github.io/Rakefile:8:in `each'
    /Users/widyaningsih/Documents/3. Andi/nurandi.github.io/Rakefile:8:in `<top (required)>'
    /usr/local/lib/ruby/gems/2.4.0/gems/rake-12.0.0/exe/rake:27:in `<top (required)>'
    

    Any idea what might be going wrong here?

  27. Michael Rose ·

    The error message is a clue. It’s looking for the domainmatrix gem. You likely don’t have it installed so it’s failing. Try gem install domainmatrix

  28. SS ·

    On an individual post, how can show comments but disable any new comments (maybe by not showing the ‘add comment’ box)? Am using staticman.

  29. Michael Rose ·

    You can do something like what I’ve done wrapping the comment form with a Liquid conditional:

    {% unless page.comments_locked == true %}
      <!-- comment form here -->
    {% else %}
      <p><em>Comments are closed.</em></p>
    {% endunless %}
    

    Then I add comments_locked: true to a post’s YAML Front Matter that I want to disable adding new comments to. You can see an example of how that looks here.

  30. Wojtek ·

    Thank you for this great article. I will have a look at how to use this in Hugo (I am just starting with Hugo but it should not be that of a big deal with the details you provided)

  31. Chris ·

    Thanks for the post. I’m looking to add comments to my blog…though I can’t help but wonder, if my website is to be interactive, why aren’t I using wordpress or something? Feels like a lot of trouble to do something that should be pretty basic