From 1f3f084f4d992853b106d14392829ac0b70b397c Mon Sep 17 00:00:00 2001 From: Greg Anderson Date: Thu, 24 Sep 2026 22:16:34 -0600 Subject: [PATCH] docs: load analytics and marketing tags only after cookie consent The docs site loaded the Reo and Apollo trackers for every visitor with no consent prompt. It now loads HubSpot's cookie banner (the portal already has an opt-in policy for docs.defectdojo.com) and waits for the visitor's choice before loading anything else: - Google Consent Mode v2 defaults to denied. - GA4 and the defectdojo.com tag container load on accept, matching defectdojo.com. Apollo now comes from that container, and Reo loads with it. - Withdrawing consent clears the tags' first-party cookies and reloads the page. Reo cookies left by the old ungated tag are removed for visitors who have not consented. - The footer gains "Privacy policy" and "Cookie settings" links in all eight languages. Cookie settings reopens the banner. - Development builds (hugo server) load no tags at all. Co-Authored-By: Claude Opus 5.5 --- docs/assets/scss/common/_custom.scss | 14 ++- docs/i18n/de.toml | 6 + docs/i18n/en.toml | 6 + docs/i18n/es.toml | 6 + docs/i18n/fr.toml | 6 + docs/i18n/it.toml | 6 + docs/i18n/ja.toml | 6 + docs/i18n/pt-br.toml | 6 + docs/i18n/zh-hans.toml | 6 + docs/layouts/_partials/footer/footer.html | 4 + .../layouts/_partials/head/script-header.html | 112 ++++++++++++++++-- 11 files changed, 167 insertions(+), 11 deletions(-) diff --git a/docs/assets/scss/common/_custom.scss b/docs/assets/scss/common/_custom.scss index b8223307136..8728346a27f 100644 --- a/docs/assets/scss/common/_custom.scss +++ b/docs/assets/scss/common/_custom.scss @@ -1412,7 +1412,8 @@ body.home .site-footer { margin-bottom: 0.375rem; } - a { + a, + .footer-link-button { color: var(--dd-dim-dark); font-size: 0.875rem; text-decoration: none; @@ -1423,6 +1424,17 @@ body.home .site-footer { text-decoration: none; } } + + // "Cookie settings" reopens the consent banner, so it is a button styled + // to match the footer links. + .footer-link-button { + padding: 0; + border: 0; + background: none; + font-family: inherit; + line-height: inherit; + cursor: pointer; + } } .footer-social { diff --git a/docs/i18n/de.toml b/docs/i18n/de.toml index 7fb6c3ad99a..cb5b08cb013 100644 --- a/docs/i18n/de.toml +++ b/docs/i18n/de.toml @@ -123,6 +123,12 @@ other = "Status" [footer_link_support] other = "Support" +[footer_link_privacy_policy] +other = "Datenschutzerklärung" + +[footer_link_cookie_settings] +other = "Cookie-Einstellungen" + [footer_rights] other = "Alle Rechte vorbehalten." diff --git a/docs/i18n/en.toml b/docs/i18n/en.toml index 29c7445acd7..e51eadd78a4 100644 --- a/docs/i18n/en.toml +++ b/docs/i18n/en.toml @@ -123,6 +123,12 @@ other = "Status" [footer_link_support] other = "Support" +[footer_link_privacy_policy] +other = "Privacy policy" + +[footer_link_cookie_settings] +other = "Cookie settings" + [footer_rights] other = "All rights reserved." diff --git a/docs/i18n/es.toml b/docs/i18n/es.toml index e4a12781eb8..e68d520b4b8 100644 --- a/docs/i18n/es.toml +++ b/docs/i18n/es.toml @@ -123,6 +123,12 @@ other = "Estado" [footer_link_support] other = "Soporte" +[footer_link_privacy_policy] +other = "Política de privacidad" + +[footer_link_cookie_settings] +other = "Configuración de cookies" + [footer_rights] other = "Todos los derechos reservados." diff --git a/docs/i18n/fr.toml b/docs/i18n/fr.toml index 20827db9d34..56c3a4bb698 100644 --- a/docs/i18n/fr.toml +++ b/docs/i18n/fr.toml @@ -123,6 +123,12 @@ other = "Statut" [footer_link_support] other = "Support" +[footer_link_privacy_policy] +other = "Politique de confidentialité" + +[footer_link_cookie_settings] +other = "Paramètres des cookies" + [footer_rights] other = "Tous droits réservés." diff --git a/docs/i18n/it.toml b/docs/i18n/it.toml index 16f3fdbb50b..21268b3cb5c 100644 --- a/docs/i18n/it.toml +++ b/docs/i18n/it.toml @@ -184,6 +184,12 @@ other = "Stato" [footer_link_support] other = "Supporto" +[footer_link_privacy_policy] +other = "Informativa sulla privacy" + +[footer_link_cookie_settings] +other = "Impostazioni dei cookie" + [footer_rights] other = "Tutti i diritti riservati." diff --git a/docs/i18n/ja.toml b/docs/i18n/ja.toml index 0054867d9ec..ed6a71493de 100644 --- a/docs/i18n/ja.toml +++ b/docs/i18n/ja.toml @@ -184,6 +184,12 @@ other = "ステータス" [footer_link_support] other = "サポート" +[footer_link_privacy_policy] +other = "プライバシーポリシー" + +[footer_link_cookie_settings] +other = "Cookie 設定" + [footer_rights] other = "無断複製・転載を禁じます。" diff --git a/docs/i18n/pt-br.toml b/docs/i18n/pt-br.toml index 98a936fd73d..ce042040968 100644 --- a/docs/i18n/pt-br.toml +++ b/docs/i18n/pt-br.toml @@ -184,6 +184,12 @@ other = "Status" [footer_link_support] other = "Suporte" +[footer_link_privacy_policy] +other = "Política de privacidade" + +[footer_link_cookie_settings] +other = "Configurações de cookies" + [footer_rights] other = "Todos os direitos reservados." diff --git a/docs/i18n/zh-hans.toml b/docs/i18n/zh-hans.toml index bdfe00d4df0..b067d6d465f 100644 --- a/docs/i18n/zh-hans.toml +++ b/docs/i18n/zh-hans.toml @@ -184,6 +184,12 @@ other = "服务状态" [footer_link_support] other = "支持" +[footer_link_privacy_policy] +other = "隐私政策" + +[footer_link_cookie_settings] +other = "Cookie 设置" + [footer_rights] other = "保留所有权利。" diff --git a/docs/layouts/_partials/footer/footer.html b/docs/layouts/_partials/footer/footer.html index b8c638fcf96..f92f4526cc2 100644 --- a/docs/layouts/_partials/footer/footer.html +++ b/docs/layouts/_partials/footer/footer.html @@ -43,6 +43,10 @@
  • {{ i18n "footer_link_trust_center" }}
  • {{ i18n "footer_link_status" }}
  • {{ i18n "footer_link_support" }}
  • +
  • {{ i18n "footer_link_privacy_policy" }}
  • + {{- if hugo.IsProduction }} +
  • + {{- end }} diff --git a/docs/layouts/_partials/head/script-header.html b/docs/layouts/_partials/head/script-header.html index b977aee216a..e05d662a8e8 100644 --- a/docs/layouts/_partials/head/script-header.html +++ b/docs/layouts/_partials/head/script-header.html @@ -1,12 +1,104 @@ - - - - \ No newline at end of file + +{{- end }}