diff --git a/marketing-website/app/datenschutz/page.tsx b/marketing-website/app/datenschutz/page.tsx
index 4630a1c..78ae644 100644
--- a/marketing-website/app/datenschutz/page.tsx
+++ b/marketing-website/app/datenschutz/page.tsx
@@ -31,7 +31,17 @@ export default function DatenschutzPage() {
Diese Website wird auf Servern der Hetzner Online GmbH in Deutschland gehostet.
Es findet kein Drittlandtransfer fuer das Hosting statt.
- Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an zuverlaessigem Betrieb).
+
+
+ Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse).
+
+
+ Interessenabwaegung: Unser berechtigtes Interesse liegt im
+ zuverlaessigen und sicheren Betrieb der Website. Ohne Hosting-Infrastruktur koennen wir unser Angebot
+ nicht bereitstellen. Die Verarbeitung beschraenkt sich auf technisch notwendige Verbindungsdaten
+ (IP-Adresse, Zeitstempel). Entgegenstehende Interessen der Betroffenen ueberwiegen nicht, da die
+ Daten nur kurzzeitig (7 Tage) gespeichert, nicht mit anderen Datenquellen zusammengefuehrt und
+ ausschliesslich zur Sicherstellung des Betriebs und der IT-Sicherheit verwendet werden.
@@ -80,9 +90,19 @@ export default function DatenschutzPage() {
5. Server-Logfiles
- Der Hosting-Provider erhebt technisch notwendige Logfiles (IP-Adresse, Browsertyp, Zeitstempel).
- Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse an der Sicherheit).
- Logfiles werden nach 7 Tagen automatisch geloescht.
+ Der Hosting-Provider erhebt technisch notwendige Logfiles (IP-Adresse, Browsertyp, Zeitstempel,
+ aufgerufene Seite, HTTP-Statuscode).
+
+
+ Rechtsgrundlage: Art. 6 Abs. 1 lit. f DSGVO (berechtigtes Interesse).
+
+
+ Interessenabwaegung: Die Erhebung von Server-Logfiles ist
+ fuer die Erkennung und Abwehr von Cyberangriffen, die Fehlerbehebung und die Gewaehrleistung der
+ Systemstabilitaet unerlasslich. Die Daten werden automatisiert nach 7 Tagen geloescht und nicht
+ zur Profilbildung oder Identifizierung einzelner Nutzer verwendet. Eine Zusammenfuehrung mit anderen
+ Datenquellen findet nicht statt. Das Interesse der Betroffenen am Schutz ihrer Daten wird durch die
+ kurze Speicherdauer und die rein technische Nutzung angemessen gewahrt.
diff --git a/marketing-website/components/layout/ScriptManager.tsx b/marketing-website/components/layout/ScriptManager.tsx
index cc4b723..61e6f18 100644
--- a/marketing-website/components/layout/ScriptManager.tsx
+++ b/marketing-website/components/layout/ScriptManager.tsx
@@ -1,31 +1,43 @@
'use client'
-import { useEffect, useRef } from 'react'
+import { useEffect, useRef, useCallback } from 'react'
/**
- * ScriptManager — consent-aware script injection.
+ * ScriptManager — active consent-aware script blocking + injection.
*
- * Listens to the `consent-change` CustomEvent dispatched by ConsentBanner
- * and injects/skips third-party scripts based on accepted categories.
+ * Two mechanisms:
+ * 1. INJECTION: Scripts in CONSENT_SCRIPTS are only injected AFTER consent.
+ * 2. BLOCKING: Existing
+ *
+ * Usage for adding new third-party scripts:
+ * Add to CONSENT_SCRIPTS below. They'll be injected only after consent.
*/
interface ConsentScript {
src: string
async?: boolean
+ id?: string
}
const CONSENT_SCRIPTS: Record = {
analytics: [
- // Example: { src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXX', async: true },
+ // { src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXX', async: true, id: 'gtag' },
+ // { src: 'https://plausible.io/js/script.js', async: true, id: 'plausible' },
],
marketing: [
- // Example: { src: 'https://connect.facebook.net/en_US/fbevents.js', async: true },
+ // { src: 'https://connect.facebook.net/en_US/fbevents.js', async: true, id: 'fb-pixel' },
+ // { src: 'https://snap.licdn.com/li.lms-analytics/insight.min.js', async: true, id: 'li-insight' },
],
functional: [
- // Example: { src: 'https://widget.example.com/chat.js', async: true },
+ // { src: 'https://widget.example.com/chat.js', async: true, id: 'chat-widget' },
],
}
@@ -46,39 +58,58 @@ function getStoredConsent(): ConsentState | null {
export default function ScriptManager() {
const injected = useRef(new Set())
- function injectScripts(consent: ConsentState) {
- const categories: (keyof typeof CONSENT_SCRIPTS)[] = []
- if (consent.analytics) categories.push('analytics')
- if (consent.functional) categories.push('functional')
- // marketing would need its own toggle in ConsentState
+ const applyConsent = useCallback((consent: ConsentState) => {
+ const accepted = new Set()
+ accepted.add('essential') // always allowed
+ if (consent.functional) accepted.add('functional')
+ if (consent.analytics) accepted.add('analytics')
- for (const cat of categories) {
+ // 1. INJECT: Add scripts from CONSENT_SCRIPTS for accepted categories
+ for (const cat of accepted) {
for (const script of CONSENT_SCRIPTS[cat] ?? []) {
if (injected.current.has(script.src)) continue
const el = document.createElement('script')
el.src = script.src
if (script.async) el.async = true
+ if (script.id) el.id = script.id
el.dataset.consent = cat
document.head.appendChild(el)
injected.current.add(script.src)
}
}
- }
+
+ // 2. ACTIVATE: Unblock