Hugo is my favourite static site generator. I use it on a site I originally created in 1996 (yes, FLF is about to be 30!). Over the last 6 months, I’ve been totally overhauling the site from top to bottom, and one of the long-term goals I had was to add in Cookie Consent.
Hugo Has Privacy Mode
One of the nice things about Hugo is they have a built in handler for Privacy Mode.
I have everything set to respect Do Not Track and use PrivacyMode whenever possible. It lightens my load a lot.
Built Into Hinode: CookieYes
The site makes use of Hinode, which has built in support for cookie consent… Kind of. They use the CookieYes service, which I get but I hate. I don’t want to offload things to a service. In fact, part of the reason I moved of WordPress and onto Hugo for the site was GDPR.
I care deeply about privacy. People have a right to privacy, and to opt in to tracking. A huge part of that is to minimize the amount of data from your own websites that are sent around to other people and saved on your own server/services!
Obviously I need to know some things. I need to know how many mobile users there are so I can make it better. I need to know what pages have high traffic so I can expand them. If everyone is going to a recap page only to try and find a gallery, then I need to make those more prominent.
In other words, I need Analytics.
And the best analytics? Still Google.
Sigh.
Alternatively: CookieConsent
I did my research. I checked a lot of services (free and pay), I looked into solutions people have implemented for Hugo, and then I thought there has to be a simple tool for this.
There is.
CookieConsent is a free, open-source (MIT) mini-library, which allows you to manage scripts — and consequently cookies — in full GDPR fashion. It is written in vanilla js and can be integrated in any web platform/framework.
And yes, you can integrate with Hugo.
How to Add CookieConsent to Hugo
First, download it. I have node set up to handle a lot of things, so I went with the easy route:
npm i vanilla-cookieconsent@3.1.0
Next, I have to add the dist files to my site. I added in a command to my package.json
:
"build:cookie": "cp node_modules/vanilla-cookieconsent/dist/cookieconsent.css static/css/cookieconsent.css && cp node_modules/vanilla-cookieconsent/dist/cookieconsent.umd.js static/js/cookieconsent.umd.js",
If you’re familiar with Hinode, may notice I’m not using the suggested way to integrate JS. If I was doing this in pure Hinode, I’d be copying the files to assets/js/critical/functional/
instead of my static
folder.
I tried. It errors out:
Error: error building site: EXECUTE-AS-TEMPLATE: failed to transform "/js/critical.bundle-functional.js" (text/javascript): failed to parse Resource "/js/critical.bundle-functional.js" as Template:: template: /js/critical.bundle-functional.js:210: function "revisionMessage" not defined
I didn’t feel like debugging the whole mess.
Anyway, once you get those files in, you need to make another special js file. This file is your configuration or initialization file. And if you look at the configuration directions, it’s a little lacking.
Instead of that, go look at their Google Example! This gives you everything you need to comply with Google Tag Manager Consent Mode, which matters to me. I copied that into /static/js/cookieconsent-init.js
and customized it. Like, I don’t have ads so I left that out.
Add Your JS and CSS
I already have a customized header (/layouts/partials/head/head.html
) for unrelated reasons, but if you don’t, copy the one from Hinode core over and add in this above the call for the SEO file:
<link rel="stylesheet" href="/css/cookieconsent.css">
Then you’ll want to edit /layouts/partials/templates/script.html
and add in this at the bottom:
<script type="module" src="/js/cookieconsent-init.js"></script>
Since your init file contains the call to the main consent code, you’re good to go!
The Output
When you visit the site, you’ll see this:

Now there’s a typo in this one, it should say “That means if you click “Reject” right now, you won’t get any Google Analytics cookies.” I fixed it before I pushed anything to production. But I made sure to specify that so people know right away.
If you click on manage preferences, you’ll get the expanded version:

The language is dry as the desert because it’s to meet Google’s specifics.
As for ‘strictly necessary cookies’?
At this time we have NO necessary cookies. This option is here as a placeholder in case we have to add any later. We’ll notify you if that happens.
And how will I notify them? By using Revision Management.