Adding comments system to a Hugo site using Giscus

  • 8 Min To Read
  • 14 May, 2023


My previous theme had several comment options built in. One of which was gitalk and so my previous post on this found setting it up super simple. However, I went and saw a new theme I liked and migrated to it in 2022. This theme only supported Discus and I’m not really a fan of it. So comments have been disabled for a while.

Looking for an option, I stumbled across this excellent blog post which details several options for implementing comments on static sites. After a quick review, I’ve chosen to explore Giscus since it has a really easy configuration approach.

My community are devs, they typically will use github and so I quite like the option of a github based commenting system as folks will need to have a github account to comment. In the future I may consider something more open, but I don’t really have much traffic, so comments are likely to be low. This option is the most suitable for me right now.

Create a repository

Initial steps are;

  • Create a public repository to hold your comments. I’ve created mine previously, there is a how to here .
  • Enable the discussions feature, github guide can be found here .
  • Install the giscus app by clicking this link.

I have restricted giscus to only access the specific repository I created for comments;

image shows the install options for giscus, github asks you whether you want giscus to have access to all repositories or specific repositories

With those steps out of the way, I can test whether giscus can access the repository directly from their site;

image shows the giscus site, the repository section has an input box where I have typed the address of my repository (justinjbird/site-blog-comments), the site has returned a success message

Now that I have proved that giscus can talk to my repository, I can get on with the rest of the configuration.

Configure giscus codeblock

The giscus site allows me to configure how I want to render the comment block and then returns the necessary code. I won’t go through every option, but once you have completed your choices, you can copy the script block. Mine looks like this;

<script src=images/posts/2023/adding-comments-to-a-hugo-site-using-giscus/""

I could technically paste this into the footer partial for my posts, but I want to allow things to be configured at the site level and have the ability to turn comments off on a specific post if I want to. First, I will set up the partial for my new code block, then go through making it a bit more dynamic.

Create partials

Hugo handles content by checking site directories first, then appending it with content from the theme directories. If a file is found in both locations, it will prioritise the site version. I need to amend the footer partial so I will make a copy of the theme version and save it at the site level. The footer partial can be found at this path for my theme;


Because I’m going to override the default behaviour, I will take a copy of this and save it in the site partials folder at this path;


Why not amend the file where it is? Because Hugo will prioritise a site file, so any changes I make will take precedence. I can make changes to the file knowing that the default is available to revert to, plus if I take newer published versions of the theme I won’t run into issues with my custom file getting overwritten.

I also want a partial for the giscus code block above. So in the site partials directory, I want to create a giscus.html file.

Populate the giscus partial

In my giscus partial I have pasted the codeblock provided by giscus and have templated it to allow me to add some control through my site. My completed partial looks like this;

{{- if (eq (.Site.Params.disableComments | default false) false) -}}
    {{- if (eq (.Params.disableComments | default false) false) -}}
        <script src=images/posts/2023/adding-comments-to-a-hugo-site-using-giscus/""
            data-theme="{{ .Site.Params.giscusTheme }}"
    {{- end -}}
{{- end -}}

There are two if statements that will control whether the comment block will appear on the page. The first if statement checks the disableComments parameter in the site’s parameter file, the second line checks the disableComments parameter in the page’s front matter. If both parameters equal false, the script will be run. Furthermore, with the default option being there if the parameter doesn’t exist it will return false. This allows me to turn off comments on a specific page but also completely disable comments across the site if I want to.

The second change I’ve made is to turn the theme option into a parameter check. This is just a preference thing - it will mean that I can adjust this setting from my param file rather than making changes to partial files. I could configure more of the options this way, but I don’t see me adjusting those settings once I’ve set them.

I need to add a partial call in my footer partial to grab my configured giscus code. My footer partial already has a lot of code in it, so I need to decide where it needs to go. I can see that the footer class creates the bar at the bottom of my posts, so my partial call should go just above that. The code I need to add is;

{{ partial "giscus" . }}

This will add the code from the giscus.html file into this partial. The important thing to note here is that “giscus” is the name of the file and since I have put the giscus file into the root of the partials directory along with the footer file, that is all I need to include. If I had stored the giscus file in a subdirectory then “giscus” would have needed to include that subdirectory (e.g. “subdirectory/giscus”).

image shows the VS Code explorer listing the layouts directory, below the layouts directory is the partials directory within that directory is both the footer.html and giscus.html files

My updated footer partial looks like this;

{{- $s := .Site.Params }}
{{ $t := .Site.Title }}
{{- if or .Params.enableMathNotation $s.enableMathNotation }}
  {{ partialCached "math" . }}
{{- end }}
{{- $iconsDir := default "icons/" .Site.Params.iconsDir }}
{{- $defaultFooterLogo := printf "%s%s" $iconsDir "apple-touch-icon.png"}}
{{ partial "giscus" . }}
<footer class="footer">
  <div class="footer_inner wrap pale">
    <img src=images/posts/2023/adding-comments-to-a-hugo-site-using-giscus/'{{ absURL (default $defaultFooterLogo $s.footerLogo) }}' class="icon icon_2 transparent" alt="{{ $t }}">
    <p>{{ T "copyright" | markdownify }}{{ with $s.since }}&nbsp;{{ . }}-{{ end }}&nbsp;<span class="year"></span>&nbsp;{{ upper $t }}. {{ T "all_rights" | markdownify }}</p>
    {{- partialCached "top" .}}

Bear in mind that this footer is specific to my site, you shouldn’t copy this code directly because it probably won’t work with your theme. You simply should be pasting the line {{ partial “giscus” . }} into your existing footer code on a new line at the appropriate place in the code. Remember you can move this line around and rebuild your site until it appears in the preferred place.

Build your site and check the comments

If everything works, I should now be able to build my site and see if it has worked…

image shows my site, with giscus comments showing!

Adding the parameters

.Site.Params looks for parameters present in your configuration file. Where these appear depends on how your theme and how you have configured things. There are several places this could appear, if you don’t know about advanced configurations chances are these will only be present in a file called config.toml at the root of your site.

If you have a more advanced configuration, then I’m going to assume that you created it and so you know what you are doing so this explanation will focus on amending the config.toml file. If your config and params have been separated or moved to the config directory, then you’ll need to update the appropriate file.

If I open my config.toml file, I need to find a line that says [Params]. Any line under that will be a parameter that is being referenced using the notation .Site.Params. If no [Params] section exists, then I can add it to the end of the file. Underneath the [Params] line, I am going to add two parameters - one for disableComments and one for the giscusTheme parameter. The code should look like this (noting that you probably will have other parameters if [Params] was already present);


This will now allow me to adjust the giscus theme and site-wide comments directly from the config file. Updating disableComments=true would disable giscus on every page of the site. If I want to disable comments on a single page them I simply need to add disableComments=true to the front matter of that specific page and giscus will be disabled.

Time to Publish

Now that I have giscus running, I can publish my site! This will enable comments on my site, and folks can now comment so long as they are logged in using github. When a comment is added to a page, it will be posted as a discussion thread to the configured repository (which you can see here ). Each time a page is loaded it will grab the related discussion from the github repository and present them on the page. Pretty cool!


So with some minor Github configuration and with the help of Giscus’ super helpful configuration page, I’ve been able to reinstate comments on my site and it was super easy! My only complaint so far is that the comment block spans the entire width of the page, if I fix that I will update the page. Please let me know in the comments if you know what to do!


If you made it all the way down here, thanks for reading my post and enjoy your day. If you have any comments or suggestions, please leave them below...

the jedi order logo