Why Hugo sites need cookie consent
Hugo generates static HTML, but that doesn't make it cookie-free. The moment you add Google Analytics, a YouTube embed, a Disqus comment box, or any third-party widget, your site sets cookies. If you serve visitors from the EU, you need consent before those cookies fire.
The upside: Hugo's template system makes this simpler than most frameworks. There's no server-side rendering, no hydration timing, and no build-time data fetching to worry about. You add one script tag in one partial, and it works across your entire site.
Quick setup: one partial, one line
Create a partial template that loads the CookieBeam script:
{{/* layouts/partials/cookie-consent.html */}}
<script src="https://cdn.cookiebeam.com/banner/YOUR_BANNER_ID/default/loader.js" async></script>Then include it in your base template, inside <head>:
{{/* layouts/_default/baseof.html */}}
<head>
<meta charset="utf-8">
<title>{{ .Title }}</title>
{{ partial "cookie-consent.html" . }}
{{/* ...rest of your head... */}}
</head>Replace YOUR_BANNER_ID with your banner ID from the CookieBeam dashboard. Deploy your site, and the banner appears on every page.
Blocking scripts until consent
If you're loading analytics or marketing scripts in Hugo templates, you need to make sure they don't fire before the visitor consents.
Option 1: CookieBeam auto-blocking (recommended)
CookieBeam's auto-blocking mode detects known tracking scripts (Google Analytics, Meta Pixel, Hotjar, etc.) and holds them until consent. If your scripts are standard <script> tags in the HTML, this works automatically with no code changes.
Option 2: Manual conditional loading
For scripts that auto-blocking doesn't cover, change their type attribute so the browser skips them, and let CookieBeam activate them after consent:
{{/* Before: fires immediately */}}
<script src="https://example.com/tracker.js"></script>
{{/* After: blocked until analytics consent */}}
<script type="text/plain" data-category="analytics"
src="https://example.com/tracker.js"></script>CookieBeam swaps the type back to text/javascript once the visitor consents to that category.
Google Consent Mode with Hugo
If you use Google Tag Manager or gtag.js, you want Consent Mode v2 so Google can model conversions even when visitors decline cookies. CookieBeam handles this automatically: it sets the default consent state (denied for analytics and ads) before your Google tags load, then updates it when the visitor consents.
Make sure your CookieBeam script appears before the GTM or gtag script in your <head>. In Hugo that means putting the cookie-consent.html partial above your analytics partial:
<head>
{{ partial "cookie-consent.html" . }}
{{ partial "analytics.html" . }}
</head>Hugo Modules and theme overrides
Static site deployment considerations
Hugo sites are typically deployed to Netlify, Vercel, Cloudflare Pages, or a plain CDN. A few things to keep in mind:
- No server-side consent check: Since Hugo generates static HTML, you can't conditionally render scripts on the server based on consent. All consent logic runs client-side, which is exactly how CookieBeam works.
- CDN caching: The CookieBeam script is loaded from
cdn.cookiebeam.com, not from your static files. It's always up to date with your latest banner configuration. - Content Security Policy: If your site sets a
Content-Security-Policyheader, addcdn.cookiebeam.comto yourscript-srcdirective. - Subresource Integrity: The CookieBeam loader is a dynamic script (it loads your latest banner config), so SRI hashes don't apply. The script is served over HTTPS from a CDN with proper cache headers.
Hugo-specific gotchas
- Hugo pipes and fingerprinting: Don't try to process the CookieBeam script through Hugo Pipes. It's an external CDN script, not a local asset. Load it directly via a
<script src>tag. - Multilingual sites: Hugo's multilingual mode (
[languages]in config) works fine with CookieBeam. The banner auto-detects the visitor's language. If you want to force a specific language per Hugo content directory, CookieBeam's config supports alanguageoverride. - Development server:
hugo serverruns onlocalhost, which CookieBeam treats as a development domain. The banner will still appear, but consent signals won't be sent to production analytics.