From f6489e77487114c9be0346215b74337ad5fe8212 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Mon, 11 May 2026 22:52:41 +0200 Subject: [PATCH] =?UTF-8?q?feat(cmp):=20Phase=202=20=E2=80=94=20send=20scr?= =?UTF-8?q?ipts=5Fblocked,=20scripts=5Freleased,=20cookies=5Fset?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ConsentBanner detects loaded scripts (analytics/marketing) and cookies after consent, sends them to the CMP backend for transparency tracking. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../components/layout/ConsentBanner.tsx | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/marketing-website/components/layout/ConsentBanner.tsx b/marketing-website/components/layout/ConsentBanner.tsx index 9274537..e54bd81 100644 --- a/marketing-website/components/layout/ConsentBanner.tsx +++ b/marketing-website/components/layout/ConsentBanner.tsx @@ -86,9 +86,40 @@ function detectDevice(): { device_type: string; browser: string; os: string } { type ConsentMethod = 'accept_all' | 'reject_all' | 'custom_selection' +interface ScriptEntry { src: string; category: string } +interface CookieEntry { name: string; domain: string; expiry_days: number; category: string } + +function detectScripts(): { blocked: ScriptEntry[]; released: ScriptEntry[] } { + const scripts = Array.from(document.querySelectorAll('script[src]')) + const released: ScriptEntry[] = [] + const blocked: ScriptEntry[] = [] + for (const el of scripts) { + const src = el.getAttribute('src') || '' + if (/google.*tag|gtag|analytics/i.test(src)) released.push({ src, category: 'analytics' }) + else if (/facebook|fbevents|linkedin|tiktok/i.test(src)) released.push({ src, category: 'marketing' }) + } + return { blocked, released } +} + +function detectCookies(): CookieEntry[] { + const cookies: CookieEntry[] = [] + for (const c of document.cookie.split(';')) { + const name = c.trim().split('=')[0] + if (!name) continue + let category = 'functional' + if (/^_ga|^_gid|^_gat/i.test(name)) category = 'analytics' + else if (/^_fb|^_gcl|^_li/i.test(name)) category = 'marketing' + else if (/^bp_consent|^session|^csrf/i.test(name)) category = 'essential' + cookies.push({ name, domain: window.location.hostname, expiry_days: 0, category }) + } + return cookies +} + async function sendConsent(consent: ConsentState, method: ConsentMethod) { try { const { device_type, browser, os } = detectDevice() + const { blocked, released } = detectScripts() + const cookies_set = detectCookies() await fetch('/api/consent', { method: 'POST', headers: { 'Content-Type': 'application/json' }, @@ -110,6 +141,9 @@ async function sendConsent(consent: ConsentState, method: ConsentMethod) { os, screen_resolution: `${screen.width}x${screen.height}`, consent_scope: 'domain', + scripts_blocked: blocked, + scripts_released: released, + cookies_set, }), }) } catch {