* feat: add GDPR cookie consent banner
Add a GDPR-compliant cookie consent banner that gates analytics (Google
Analytics) and functional cookies (comments) until user consent is given.
Features:
- Theme-consistent styling using CSS variables (light/dark mode)
- Settings panel with category toggles (necessary, analytics, functional)
- Consent stored in cookie for 365 days
- Google Analytics only loads after analytics consent
- Comments only load after functional consent
- Translations for all 32 supported languages
- Accessible with proper ARIA attributes and focus management
Configuration in hugo.yaml:
params:
cookies:
enabled: true
categories:
analytics: true
functional: true
When cookies.enabled is false, scripts load normally without consent gating.
Closes #412
* refactor: move consent-gated GA to cookies/analytics.html
Move Google Analytics consent logic to avoid shadowing Hugo's internal
`_internal/google_analytics.html` template.
Changes:
- Rename google_analytics.html → cookies/analytics.html
- Update head.html to conditionally load:
- cookies.enabled=true: cookies/analytics.html (consent-gated)
- cookies.enabled=false: Hugo's _internal/google_analytics.html
- Align cookies/analytics.html with Hugo's internal template:
- Support Privacy.GoogleAnalytics.Disable setting
- Support Privacy.GoogleAnalytics.RespectDoNotTrack setting
- Add UA- prefix deprecation warning
Note: Custom JS is required for consent-gated GA because Hugo templates
render at build time, but consent happens at runtime. We cannot call
Hugo's internal template after the user grants consent - we must
dynamically inject the GA script via JavaScript.
* style: indent cookies/analytics.html
* refactor: don't use default, put default configurations in params.toml
* fix: don't use `description` as translation key because it's reserved and will throw error
* fix: remove footer/components/custom-font.html call
* fix: banner showSettings key
* style: indent comments/include
* Add missing article.alert translation back
* style: format i18n toml files
* style: indent head/head.html
* style adjustment
* style: add missing -
* style: format demo/config/params.toml
* style: remove redundant comments from cookies.scss
* style: update box-shadow for cookie banner content
---------
Co-authored-by: delize <4028612+delize@users.noreply.github.com>
Co-authored-by: Jimmy Cai <jimmy@cai.im>
189 lines
5.4 KiB
TOML
189 lines
5.4 KiB
TOML
mainSections = ["post"]
|
|
featuredImageField = "image"
|
|
rssFullContent = true
|
|
# Accepted values: "default", "lastmod"
|
|
# default = see https://gohugo.io/quick-reference/glossary/#default-sort-order
|
|
# lastmod = sort by last modified date, in descending order
|
|
SortBy = "default"
|
|
|
|
[footer]
|
|
since = 2026
|
|
customText = ""
|
|
|
|
[dateFormat]
|
|
published = ":date_full"
|
|
lastUpdated = ":date_full"
|
|
|
|
[sidebar]
|
|
compact = false
|
|
avatar = ""
|
|
|
|
[article]
|
|
headingAnchor = false
|
|
math = false
|
|
toc = true
|
|
readingTime = true
|
|
|
|
[article.license]
|
|
enabled = false
|
|
default = "Licensed under CC BY-NC-SA 4.0"
|
|
|
|
# Mermaid diagram configuration
|
|
# Diagrams are only loaded when mermaid code blocks are present
|
|
# Theme auto-switches based on site light/dark mode
|
|
[article.mermaid]
|
|
# Visual style: classic or handDrawn (sketch style)
|
|
look = "classic"
|
|
# Theme for light mode: default, neutral, dark, forest, base, null
|
|
lightTheme = "default"
|
|
# Theme for dark mode: default, neutral, dark, forest, base, null
|
|
darkTheme = "dark"
|
|
# Custom theme variables for light mode (only works with lightTheme: base)
|
|
# lightThemeVariables = { primaryColor = "#ff0000" }
|
|
# Custom theme variables for dark mode (only works with darkTheme: base)
|
|
# darkThemeVariables = { primaryColor = "#00ff00" }
|
|
# Security level: strict (default), loose, antiscript, sandbox
|
|
# Set to "loose" to enable HTML labels like <br/>
|
|
securityLevel = "strict"
|
|
# Enable HTML labels in diagrams (requires securityLevel: loose)
|
|
htmlLabels = true
|
|
# Make diagram backgrounds transparent (default: false)
|
|
# Can also be set per-diagram with %%transparent%% directive
|
|
transparentBackground = false
|
|
|
|
[article.alertIcon]
|
|
# Alert icons for different alert types (note, tip, important, warning, caution)
|
|
note = "📝"
|
|
tip = "💡"
|
|
important = "📌"
|
|
warning = "⚠️"
|
|
caution = "🚨"
|
|
|
|
[widgets]
|
|
homepage = []
|
|
page = []
|
|
|
|
[opengraph.twitter]
|
|
site = ""
|
|
card = "summary_large_image"
|
|
|
|
[colorScheme]
|
|
toggle = true
|
|
default = "auto"
|
|
|
|
[imageProcessing.cover]
|
|
enabled = true
|
|
|
|
[imageProcessing.content]
|
|
enabled = true
|
|
|
|
# GDPR Cookie Consent Configuration
|
|
# When enabled, analytics and functional cookies require user consent
|
|
[cookies]
|
|
enabled = false
|
|
showSettings = true
|
|
|
|
[cookies.categories]
|
|
analytics = true
|
|
functional = true
|
|
|
|
[comments]
|
|
enabled = true
|
|
provider = "disqus"
|
|
|
|
[comments.disqusjs]
|
|
shortname = ""
|
|
apiUrl = ""
|
|
apiKey = ""
|
|
admin = ""
|
|
adminLabel = ""
|
|
|
|
[comments.utterances]
|
|
repo = ""
|
|
issueTerm = "pathname"
|
|
label = ""
|
|
|
|
[comments.beaudar]
|
|
repo = ""
|
|
issueTerm = "pathname"
|
|
label = ""
|
|
theme = ""
|
|
|
|
[comments.remark42]
|
|
host = ""
|
|
site = ""
|
|
locale = "en"
|
|
max_shown_comments = 15
|
|
show_email_subscription = true
|
|
|
|
[comments.vssue]
|
|
platform = ""
|
|
owner = ""
|
|
repo = ""
|
|
clientId = ""
|
|
clientSecret = ""
|
|
autoCreateIssue = false
|
|
|
|
# Waline client configuration see: https://waline.js.org/en/reference/component.html
|
|
[comments.waline]
|
|
serverURL = ""
|
|
lang = ""
|
|
pageview = ""
|
|
emoji = ["https://unpkg.com/@waline/emojis@1.0.1/weibo"]
|
|
requiredMeta = ["name", "email", "url"]
|
|
|
|
[comments.waline.locale]
|
|
admin = "Admin"
|
|
placeholder = ""
|
|
|
|
[comments.twikoo]
|
|
envId = ""
|
|
region = ""
|
|
path = ""
|
|
lang = ""
|
|
|
|
# See https://cactus.chat/docs/reference/web-client/#configuration for description of the various options
|
|
[comments.cactus]
|
|
defaultHomeserverUrl = "https://matrix.cactus.chat:8448"
|
|
serverName = "cactus.chat"
|
|
siteName = "" # You must insert a unique identifier here matching the one you registered (See https://cactus.chat/docs/getting-started/quick-start/#register-your-site)
|
|
|
|
[comments.giscus]
|
|
repo = ""
|
|
repoID = ""
|
|
category = ""
|
|
categoryID = ""
|
|
mapping = "title"
|
|
lightTheme = "light"
|
|
darkTheme = "dark_dimmed"
|
|
reactionsEnabled = 1
|
|
emitMetadata = 0
|
|
inputPosition = "top"
|
|
lang = "en"
|
|
strict = 0
|
|
loading = "lazy"
|
|
|
|
[comments.gitalk]
|
|
owner = ""
|
|
admin = ""
|
|
repo = ""
|
|
clientID = ""
|
|
clientSecret = ""
|
|
proxy = ""
|
|
|
|
[comments.cusdis]
|
|
host = "https://cusdis.com"
|
|
id = ""
|
|
|
|
# Comentario client configuration
|
|
[comments.comentario]
|
|
url = ""
|
|
autoInit = false
|
|
autoNonInteractiveSso = false
|
|
cssOverride = ""
|
|
lang = ""
|
|
liveUpdate = false
|
|
maxLevel = 0
|
|
noFonts = false
|
|
theme = ""
|