Config GitLab Repo for Staticman

Update: I suggest reading a newer tutorial.

To keep focused on the technical setup, please refer to the introduction of this series for the reasons of choosing Staticman and GitLab.


To set up unauthenticated commenting system on GitLab pages.

GitLab Page with Staticman

Demo GitLab Page with Staticman v3

Built on 14/09/2018

This post aims at providing a walkthrough to the GitLab repo setup. If you want to host your own Staticman API instance, you may refer to the next post in this series.

Existing solution: GitHub mirror to GitLab

Staticman is a system which allows comments on static sites. However, it was limited to GitHub. Support for GitLab had been the most wanted feature for two years.

Zongren has proposed a wonderful workaround which makes use of GitHub webhooks and GitLab triggers. However, that’s not a genuine open source solution as it still depends on proprietary GitHub. Some users find this makes no sense at all.

Thanks to Nicolas Tsim’s pull request, it’s possible to run Staticman with native GitLab support. If you’re a free software purist, you may download the source code of everything and host them yourself.

Technical setup

This article assumes that you have

  1. a GitLab repo (for your blog)
  2. a dummy GitLab account (the “GitLab bot”, you may use my bot @staticmanlab.)
  3. an instance of Staticman v3 API server holding the bot’s person access token. (Again, you may use my instance of the API server running on a Heroku free dyno.)

In case of doubts, you may view my demo project (source).

What #3 does is to send data from an HTML <form> (as a POST request) to the API server, which instructs #2 the GitLab bot to create merge request to #1 the GitLab repo for your blog.

If you’re unsure what my API instance do, I’ll invite you to view its source code. In particular, my customizations against staticman/dev branch.

  1. In your GitLab project page, go to Settings → Members.

  2. Grant the GitLab bot “developer” access.

    (Edited on Nov 18, 2018, as a follow-up to halogenica/beautifulhugo#222)

    According to the setup guide in Staticman PR 219, at this point, you’ll be able to post comments. However, as can be seen from my comments, I stopped messing things up after including my OAuth application ID and secret for authenticated comments in config file staticman.yml. Even though I’m not 100% sure if the steps 3–6 are required, I advise you following them.

    Steps 3–7 are optional steps for authenticated comments. You may copy a suitable staticman.yml **file from your blogging theme, change/delete the reCaptcha key, and proceed with step 8. (say, the one from Beautiful Hugo)

     2  allowedFields: ["name", "email", "website", "comment"]
     3  branch            : "master"
     4  commitMessage     : "New comment in {options.slug}"
     5  path: "data/comments/{options.slug}"
     6  filename          : "comment-{@timestamp}"
     7  format            : "yaml"
     8  moderation        : true
     9  requiredFields    : ['name', 'email', 'comment']
    10  transforms:
    11email           : md5
    12  generatedFields:
    14  type          : "date"
    15  options:
    16    format      : "iso8601"
    17  reCaptcha:
    18enabled: true
    19siteKey: "6LeGeTgUAAAAAAqVrfTwox1kJQFdWl-mLzKasV0v"
    20secret: "hsGjWtWHR4HK4pT7cUsWTArJdZDxxE2pkdg/ArwCguqYQrhuubjj3RS9C5qa8xu4cx/Y9EwHwAMEeXPCZbLR9eW1K9LshissvNcYFfC/b8KKb4deH4V1+oqJEk/JcoK6jp6Rr2nZV4rjDP9M7nunC3WR5UGwMIYb8kKhur9pAic="

    For instance, you may view my second demo site (with proper comment reply support) and its source.

  3. Under your account settings, choose Applicatons.

  4. Add a new application (for visitors to authenticate themselves on your site).

    Fields actions
    Name Whatever name you like, so that you can recognise it in the future.
    Redirect URI Your blog URL; “localhost” for local testing
    Scopes api, ☑ read_repository
  5. The application ID and secret should appear.

  6. GET /encrypt application ID and secret. You may enter the following URL in the address bar of your web browser.


    You may replace <your-api-instance> and <text> with the domain name of your Staticman v3 API instance and the text to be encrypted respectively. For example, if you’re using your API instance, you may type

    and replace l3lsdh5 with your actual application ID and secret.

  7. Hook the API server and the bot up with the GitLab repo.

    Add the encrypted strings to your staticman.yml. Replace the fields with yours. You may view my staticman.yml as a reference.

        clientId: phApfhlPYrReszwh9V...
        clientSecret: LyknknJah7mbYWtbcgET...

    Add these lines (for generated fields) to this YML files as well to avoid MISSING_FIELDS error, or even copy the existing examples.

          type: user
            property: "type"
          type: user
            property: "email"
          type: user
            property: "username"
          type: user
            property: "name"

    The GitLab bot grabs this YML file for the API server to decide which fields to be written to your GitLab repo. The target path inside the repo is determined by

      # Destination path (directory) for the data files. Accepts placeholders.
      path: "data/comments/{options.slug}"

    Staticman is only responsible for delivering the comments from commentators to the site owner’s designated path (inside the GitLab repo). You have to consult your blog template’s README / documentation in order to set up the path correctly for displaying comments.

  8. Hook the HTML form up with the Staticman API server.

    Edit your site config file for your blog. (The actual file name dependes on the generator. Hugo calls it config.toml; Jekyll names it _config.yml.) Include the API address as well as the merge request target URL. Actual setup can vary depending on your site generator/theme.

    However, the basic working principle is universal. The code in the blog template’s HTML <form action="{{ code }}"> determines the recipient API server. Take this blog’s theme (Beautiful Hugo) as an example.

     $ git grep '<form'
     layouts/partials/staticman-comments.html:<form class="js-form form" method="post
     " action="{{ .Site.Params.staticman.api }}">

    The code .Site.Params.staticman.api is found, meaning that Staticman’s api has to be configured.

    In any case, the API URL in the form action has comply with the new standard for the /entry endpoint.

    • :service: currently supports github and gitlab (e.g. gitlab)
    • :username: your GitHub/GitLab user name (e.g. vincenttam)
    • :repository: your repository name (e.g. test-hugo-staticman)
    • :branch: the branch against which the GitHub/GitLab bot create pull/merge request (e.g. master)
    • :property: this matches exactly one of the unindented lines in staticman.yml. See its top comment block to know more.
  9. (Optional) Set up reCAPTCHA to stop SPAM / machine generated comments.

    Beautiful Hugo’s README provided a simple way to set up the site config files. However, the author of this README simply put reCAPTCHA’s secret field. without further explanations. In fact, according the official documentation about staticman.yml, this secret field should be /encrypted like the application ID in step #4.

    In staticman.yml:

        enabled: true
        siteKey: "6LeGeTgUAAAAAAqVrfTwox1kJQFdWl-mLzKasV0v"
        secret: "hsGjWtWHR4H...ur9pAic="

    In config.toml:

      sitekey = "6LeGeTgUAAAAAAqVrfTwox1kJQFdWl-mLzKasV0v"
      secret = "hsGjWtWHR4H...ur9pAic="

Use my API instance for testing and educational purposes only. Never use it for production since Heroku free dynos aren’t for that. (Free dynos idle after 30 minutes of inactivity.)

config file intepreted by function
(_)?config.* static site generator The blog uses this to send form to the API.
staticman.yml Staticman API server The GitLab bot creates merge requests according to this file.


  1. Now, you should be able ot submit comments by clicking .

  2. To approve them comment, log in the site owner’s GitLab account, go to your repo page and click Merge Requests.

  3. Accept comment?

    decision action
    merge, ☑ delete source branch
  4. Wait until the site rebuild finishes. (You may view the progress in CI / CD → Pipelines.)

Additional feature: posting without approval

Provided that the target audience of the blog is somebody you trust (say, your colleagues), you may want their comments instantly available after the site rebuild without your approval.

Since master branch is a protected branch by default, the site owner has to grant rights for “developers” to merge and to push against master branch.

  1. Go to the repo’s Settings ➔ Repository .
  2. In Protected branches, at the row representing master branch, for each drop-down list, uncheck “Masters” and check “Developers + Masters”.


  1. Staticman pull request #219
  2. GitLab permission table
  3. Staticman issue #22


Vincent Tam's gravatar

Vincent Tam Paul Rubens

It seems to be an error in staticman.yml. You may consult my article on Staticman erros for a more detailed analysis of Staticman’s API’s error.

You may find the following repos useful


Ritesh Raj Sarraf's gravatar

Ritesh Raj Sarraf

I have tried to follow your article and setup comments for my website. Even though I use Hugo and the very same theme that you are using, I still have a hard time setting up comments with Hugo.

You’ve already done great work by providing this article. But turns out I am a dumb noob in web related stuff. If you would consider, would you please consider looking into my website as to what I am doing wrong here.

I have cloned my website at:

Note: I have not pushed this to my production site yet. But the gitlab application_id and secrets I created included URI for localhost too. So ideally, if this can be worked on a localhost setup, it’d work on production too.

Vincent Tam's gravatar

Vincent Tam Ritesh Raj Sarraf

You’ve already done great work by providing this article. But turns out I am a dumb noob in web related stuff. If you would consider, would you please consider looking into my website as to what I am doing wrong here.

I’ve just taken a glance. You’re using authenticated comments? If not, gitlabAuth is irrelevant. See for an example.

The only free (as in free beer) service that I can offer is a quote from Robert Kyosaki.

The trouble with school is they give you the answer, then they give you the exam. That’s not life.

Welcome to Solarized Sublime Sekai, where I share my experience about learning from errors.

  • Solarized is a color theme not in Beautiful Hugo. I’ve made the current one by testing and tweaking.
  • Sublime is an advanced text editor. Its features have to be learnt by practising.
  • Sekai has been introduced in the home page.

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