Skip to content

Commit cf572f3

Browse files
Christian Shearerclaude
andcommitted
Add GA4 consent mode v2 with cookie consent banner
- Consent defaults to denied before gtag loads (analytics_storage, ad_storage, ad_user_data, ad_personalization all denied) - Cookie banner shows on first visit with Accept/Decline - Accept: updates consent to granted, stores in localStorage - Decline: stays denied, banner dismissed - Returning visitors: reads localStorage, no banner shown - Compliant with GDPR/EEA consent mode v2 requirements Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent a2c9dbc commit cf572f3

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

src/server/brand.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,13 @@ export function brandFonts(): string {
6565
<link rel="preconnect" href="https://fonts.googleapis.com">
6666
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
6767
<link href="https://fonts.googleapis.com/css2?family=Mulish:wght@400;500;600;700;800;900&family=Inter:wght@400;500;600;700&display=swap" rel="stylesheet">
68-
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CGCVGY357V"></script>
69-
<script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}gtag('js',new Date());gtag('config','G-CGCVGY357V');</script>`;
68+
<script>
69+
window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);}
70+
gtag('consent','default',{analytics_storage:'denied',ad_storage:'denied',ad_user_data:'denied',ad_personalization:'denied',wait_for_update:500});
71+
if(localStorage.getItem('regen_consent')==='granted'){gtag('consent','update',{analytics_storage:'granted'});}
72+
gtag('js',new Date());gtag('config','G-CGCVGY357V');
73+
</script>
74+
<script async src="https://www.googletagmanager.com/gtag/js?id=G-CGCVGY357V"></script>`;
7075
}
7176

7277
// ---------------------------------------------------------------------------
@@ -573,5 +578,32 @@ export function brandFooter(opts?: FooterOptions): string {
573578
574579
<div class="regen-footer__legal">&copy; ${new Date().getFullYear()} Regen Network Development, PBC. Licensed under <a href="https://github.com/regen-network/regen-compute/blob/main/LICENSE" target="_blank" rel="noopener">Apache 2.0</a>.</div>
575580
</footer>
581+
582+
<div id="consent-banner" style="display:none;position:fixed;bottom:0;left:0;right:0;z-index:10000;background:#fff;border-top:1px solid #e5e7eb;padding:14px 24px;box-shadow:0 -2px 12px rgba(0,0,0,0.08);font-family:'Inter',Arial,sans-serif;font-size:13px;color:#374151;">
583+
<div style="max-width:960px;margin:0 auto;display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;">
584+
<p style="margin:0;line-height:1.5;flex:1;min-width:200px;">We use cookies to understand how visitors use our site. No data is sold or used for ads. <a href="https://regen.network/privacy-policy" target="_blank" rel="noopener" style="color:#4FB573;">Privacy Policy</a></p>
585+
<div style="display:flex;gap:8px;flex-shrink:0;">
586+
<button onclick="acceptConsent()" style="background:#4FB573;color:#fff;border:none;border-radius:6px;padding:8px 18px;font-size:13px;font-weight:600;cursor:pointer;">Accept</button>
587+
<button onclick="declineConsent()" style="background:none;color:#9ca3af;border:1px solid #e5e7eb;border-radius:6px;padding:8px 14px;font-size:13px;cursor:pointer;">Decline</button>
588+
</div>
589+
</div>
590+
</div>
591+
<script>
592+
function acceptConsent(){
593+
localStorage.setItem('regen_consent','granted');
594+
gtag('consent','update',{analytics_storage:'granted'});
595+
document.getElementById('consent-banner').style.display='none';
596+
}
597+
function declineConsent(){
598+
localStorage.setItem('regen_consent','denied');
599+
document.getElementById('consent-banner').style.display='none';
600+
}
601+
(function(){
602+
var c=localStorage.getItem('regen_consent');
603+
if(c) return; // already chose
604+
// Show banner — consent mode defaults already set to denied in <head>
605+
document.getElementById('consent-banner').style.display='block';
606+
})();
607+
</script>
576608
`;
577609
}

0 commit comments

Comments
 (0)