Update
Heroku is discontinuing its free product plans. Use one of the alternatives discussed in this GitHub issue. I’m using Fly.

Setting up a commenting system with Staticman on this site (which uses the Minimal Mistakes Jekyll theme and is hosted on GitLab Pages) has not been easy, but thanks to guides by Vincent Tam and Blogger Bust, I managed to figure things out. Here are the steps I followed.

Setting things up

  1. Create a new GitLab account to act as the bot.

  2. Generate a personal access token for the new GitLab bot account, with the api and read_repository scopes enabled, and store it securely.

  3. Login to the GitLab account which hosts the site repository. In the repository, go to Members and grant the bot account access as a Developer to the repository.

  4. Create a Heroku account.

    Note
    I have two-factor authentication activated on both my GitLab bot and Heroku accounts, and this set-up worked fine for me.

  5. Download and install the Heroku CLI:

    curl https://cli-assets.heroku.com/install.sh | sh
    
  6. Verify your Heroku CLI installation:

    heroku --version
    

Preparing the Staticman files

  1. Clone the Staticman repository and navigate to its directory:

    git clone https://github.com/eduardoboucas/staticman
    cd staticman
    
  2. Generate a RSA private and public key pair:

    openssl genpkey -outform PEM -algorithm RSA > staticman_key
    openssl pkey -inform PEM -in staticman_key -pubout > staticman_key.pub
    
  3. Create a Procfile with the line web: npm start at the repository’s root:

    echo web: npm start > Procfile
    
  4. Create a file called config.production.json in the repository’s root and paste the following:

    {
      "gitlabToken": process.env.GITLAB_TOKEN,
      "githubToken": process.env.GITHUB_TOKEN,
      "rsaPrivateKey": JSON.stringify(process.env.RSA_PRIVATE_KEY)
    }
    
  5. Add config.production.json as an exception to .gitignore:

    echo "!"config.production.json >> .gitignore
    

Deploying the Heroku app

  1. Login to Heroku using the CLI:

    heroku login
    
  2. Create a new app on Heroku for the Staticman instance (set an ${appname} to prevent a randomly-generated one):

    heroku create ${appname}
    
  3. Upgrade the app to the latest stack:

    heroku stack:set heroku-20
    
  4. Set the Staticman environment variables in the app, replacing ${token} with the GitLab personal access token generated earlier:

    heroku config:set NODE_ENV="production"
    heroku config:set GITLAB_TOKEN="${token}"
    heroku config:set RSA_PRIVATE_KEY="$(cat staticman_key)"
    
  5. Create a production branch from the main branch:

    git checkout -b production master
    
  6. Stage and commit the changes:

    git add config.production.json Procfile .gitignore
    git commit -m "Set up Staticman v3 for deployment to Heroku"
    
  7. Push to Heroku to deploy the app:

    git push heroku production:master
    
  8. Check if the app works by opening https://${appname}.herokuapp.com/. The message Hello from Staticman version 3.0.0! should appear.

    Note
    If you make any changes to the Staticman repository later on, simply commit the changes as usual and push with git push heroku production:master.

    I made a small change in lib/Staticman.js (line 293) to remove the comment table from rendering in the pull request message body:

    let message = this.siteConfig.get('pullRequestBody') // + markdownTable(table)
    

Get a reCAPTCHA key

reCAPTCHA is optional, but it has become a requirement for me due to the number of spambot comments I was getting. Get a reCAPTCHA v2 Checkbox site key for your site’s domain. Then, encrypt the site secret using the https://${appname}.herokuapp.com/v3/encrypt/${text-to-encrypt} endpoint. The site key and encrypted secret must be entered in the site’s configuration files.

Configuring the Minimal Mistakes Jekyll theme

To modify the reCAPTCHA’s theme, copy _includes/comments.html and change line 75 as follows:

                  <div class="g-recaptcha" data-sitekey="{{ site.reCaptcha.siteKey }}" data-theme="{{ site.reCaptcha.theme | default: 'light' }}"></div>

Note
For Minimal Mistakes v4.24.0 and below, be sure to copy the latest available version of _includes/comments.html, i.e. from the latest commit in the default branch, as it includes a new feature (sort comments by date ascending).

Make the following changes to _config.yml in the site repository:

comments:
  provider: staticman_v2
  staticman:
    branch: main
    endpoint: https://${appname}.herokuapp.com/v3/entry/gitlab/
reCaptcha:
  siteKey: "your_site_key"
  secret: "your_encrypted_site_secret"
  theme: dark  # "dark" or "light" (default)

Paste the following in _staticman.yml in the site repository:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
comments:
  allowedFields: [name, email, url, message]

  branch: main  # your default branch

  commitMessage: New comment by {fields.name}

  filename: comment-{@timestamp}

  format: yml

  generatedFields:
    date:
      type: date
      options:
        format: iso8601

  moderation: true

  path: _data/comments/{options.slug}

  requiredFields: [name, email, message]

  transforms:
    email: md5

  reCaptcha:
    enabled: true
    siteKey: "your_site_key"
    secret: "your_encrypted_site_secret"

Note
I’m using unauthenticated comments with moderation. If moderation is set to false, the bot must have elevated permissions (e.g. Maintainer instead of Developer), or the main branch of the repository must be unprotected; otherwise, the bot will attempt to commit directly to the main branch and fail. See this guide on the Performance Matters blog for other configuration options.

Additionally, copy _includes/comment.html and make the following change to line 7, so that no link will appear if a commenter omits the website URL field:

{% unless include.url == nil or include.url == empty or include.url == "" %}

Note
Finally, I changed the date format to match that of my locale, i.e. en-GB.

In _config.yml, I defined the date format:

long_date_format: "%-d %B %Y at %H:%M"

I changed line 16 of _includes/comment.html as follows:

        <time datetime="{{ include.date | date_to_xmlschema }}" itemprop="datePublished">{{ include.date | date: long_date_format }}</time>

I then added the following to the very top of _includes/comment.html:

{% assign long_date_format = site.long_date_format | default: "%B %-d, %Y at %I:%M %p" %}

Stage, commit, and push the changes to rebuild the site.

Go to a post on the newly-built site and submit a test comment. A pull request will be created by the bot with the new comment if the submission is successful. Merge it to publish the comment on the site.

To-do

Nested comments and email notifications. I’m working on it 😉. I think the following links will come in handy:

  1. Staticman Repo Setup Errors - Solarized Sublime Sekai
  2. Improving static comments with Jekyll & Staticman - Made Mistakes
  3. Going static part 2: static comments - Made Mistakes
  4. Staticman…The Journey Continues - Dan C Williams
  5. Hugo + Staticman: Nested Replies and E-mail Notifications - Dan C Williams
  6. Adding Staticman Comments - Performance Matters
  7. Staticman: Adding comments to my Jekyll site - Gabe’s Code
  8. Staticman - Solarized Sublime Sekai

Comments

Leave a comment

Your email address will not be published. Required fields are marked *.

Loading...