Hugo Comments With Docsy and Giscus

Integrate comments into a static site using Giscus and Github Discussions

Giscus is a super lightweight comment system powered by GitHub Discussions. It uses a GitHub app plus a small JavaScript snippet to embed a comment section on your site. If someone comments, it automatically creates a GitHub Discussion and syncs replies. See the bottom of this post for a live example. There’s no backend, no database, and if your readers have a GitHub account, that’s all they need. Here’s how I integrated it into a Hugo site using the Docsy theme.

Why Giscus?

  • No backend setup: works perfectly with static sites.
  • Comments are stored as GitHub Discussions.
  • Authentication is GitHub-based so no extra accounts.
  • No cookies, no tracking.
  • Tiny frontend (one JS file).
  • Markdown formatting and reactions work out of the box.

Setup

1. Configure Your GitHub Repo + Giscus

Enable Discussions in your repository:

  • Create a new public repo
  • Enable discussions
  • Install the Giscus App in the repo (I recommend ONLY enabling it for the single repo)
  • Go to giscus.app and configure. I use URL mapping and the General category. The app with generate a <script> block like this:
<script src="https://giscus.app/client.js"
        data-repo="[ENTER REPO HERE]"
        data-repo-id="[ENTER REPO ID HERE]"
        data-category="[ENTER CATEGORY NAME HERE]"
        data-category-id="[ENTER CATEGORY ID HERE]"
        data-mapping="pathname"
        data-strict="0"
        data-reactions-enabled="1"
        data-emit-metadata="0"
        data-input-position="bottom"
        data-theme="preferred_color_scheme"
        data-lang="en"
        crossorigin="anonymous"
        async>
</script>

Hang to this for the next step.

2. Create a comments snippet

  • Add params.giscus to your hugo.toml and plug in the values from the <script> output.
[params.giscus]
repo = ""
repo_id = ""
category_id = ""

category = "General"
mapping = "url"
theme = "preferred_color_scheme"
data_reactions = "1"
data_input_position="top"
  • Create `layout/partials/comments.html to render the <script>:
{{ if .Site.Params.giscus.repo }}
<div id="comments" style="margin-top: 2rem;">
  <script src="https://giscus.app/client.js"
          data-repo="{{ .Site.Params.giscus.repo }}"
          data-repo-id="{{ .Site.Params.giscus.repo_id }}"
          data-category="{{ default "General" .Site.Params.giscus.category }}"
          data-category-id="{{ .Site.Params.giscus.category_id }}"
          data-mapping="{{ default "url" .Site.Params.giscus.mapping }}"
          data-strict="0"
          data-reactions-enabled="{{ default "1" .Site.Params.giscus.data_reactions }}"
          data-emit-metadata="0"
          data-input-position="{{ default "top" .Site.Params.giscus.data_input_position }}"
          data-theme="{{ default "preferred_color_scheme" .Site.Params.giscus.theme }}"
          data-lang="en"
          data-loading="lazy"
          crossorigin="anonymous"
          async>
  </script>
</div>
{{ end }}

3. Add the partial to your layout. In layouts/blog/content.html I put:

<div>
...
{{ if .IsPage }}
  {{ partial "comments.html" . }}
{{ end }}
</div>

Conclusion

Push it, test it, and you should see the Giscus thread at the bottom of your posts. If a page hasn’t been commented on before, Giscus will create the discussion when someone does.

Try it out below!