Das AddOn stellt eine DSGVO-konforme Lösung für die Einholung von Einverständniserklärungen zu Cookies und externen Diensten bereit. Website-Besucher erhalten eine Consent-Box, in der einzelne Dienste-Gruppen akzeptiert oder abgelehnt werden können. Technisch notwendige Dienste bleiben dabei immer aktiv.
Kernfunktionen:
- Datenschutz-Opt-In-Banner für Dien## 🔍 Debug-Modus
Consent-Debug-Panel: Seit Version 4.4.0 verfügbar für Entwickler und Troubleshooting.
Aktivierung:
- Domain-Konfiguration: Debug-Modus in Domain-Einstellungen aktivieren
- Backend-Login erforderlich: Nur für angemeldete Administrator sichtbar
Features:
- Live-Anzeige aller Cookie-Stati
- Google Consent Mode Integration
- LocalStorage-Übersicht
- Service-Status-Monitor
- Menü-Indikator mit Symbol bei aktivem Debug-Modusg-Panel:** Seit Version 4.4.0 verfügbar für Entwickler und Troubleshooting.
Aktivierung:
- Domain-Konfiguration: In Domains → Debug-Modus auf "Aktiviert" setzen
- Backend-Login erforderlich: Debug-Panel nur für angemeldete Backend-Benutzer sichtbar
Features:
- 🎯 Google Consent Mode v2 Status: Zeigt aktiven Modus (Deaktiviert ❌ / Automatisch 🔄 / Manuell ⚙️)
- Live-Anzeige aller Consent-Stati: analytics_storage, ad_storage, ad_user_data, etc.
- Service-Status-Monitor: Welche Services sind aktiv und welchen Consent-Gruppen zugeordnet
- Cookie-Analyse: Strukturierte Darstellung aller Cookies mit JSON-Parsing
- LocalStorage-Übersicht: Einblick in alle gespeicherten Consent-Daten
- Echtzeit-Updates: Status ändert sich live bei Consent-Änderungen
- Menü-Indikator: Symbol im Backend-Menü bei aktivem Debug-Modus
Sicherheit: Debug-Panel ist aus Sicherheitsgründen nicht für normale Website-Besucher verfügbar.s
- Flexible Gruppierung von Diensten
- Nachträgliche Änderung der Einstellungen möglich
- Vollständig anpassbare Texte und Designs
- Google Consent Mode v2 Integration
- Mehrsprachig und Multi-Domain-fähig
Wichtiger Haftungsausschluss: Die mitgelieferten Texte und Cookie-Definitionen sind ausschließlich Beispiele und können unvollständig oder nicht aktuell sein.
Rechtliche Verantwortung: Website-Betreiber und Entwickler sind eigenverantwortlich dafür zuständig, dass:
- Die Funktionalität der Abfrage den rechtlichen Anforderungen entspricht
- Alle Texte, Dienste und Cookie-Beschreibungen korrekt und vollständig sind
- Die Integration ordnungsgemäß erfolgt
- Die Lösung der geltenden Rechtslage und den Datenschutzbestimmungen entspricht
Empfehlung: Für die Formulierung der Texte und Cookie-Listen sollten Datenschutzbeauftragte oder die Rechtsabteilung konsultiert werden.
# AddOn über REDAXO Installer herunterladen und installierenQuickstart-Assistent: Beim ersten Aufruf der Konfiguration führt Sie ein 7-stufiger Assistent durch das komplette Setup - von der Domain-Konfiguration bis zur Theme-Auswahl.
Setup-Varianten wählen:
- Minimal: Nur essentieller Service für datenschutz-minimale Websites
- Standard: Vollständige Service-Sammlung für umfassende Cookie-Verwaltung
Unter Domains die Website-Domain hinterlegen (ohne Protokoll):
beispiel.de
www.beispiel.de
Wichtig: Assets müssen im Template eingebunden werden, damit der Consent Manager und die Inline-Blocker funktionieren!
PHP-Aufruf (empfohlen):
<?php
// Standard-Integration (alles in einem)
echo consent_manager_frontend::getFragment(0, 0, 'consent_manager_box_cssjs.php');
// Oder Komponenten einzeln laden (mehr Flexibilität):
?>
<style><?php echo consent_manager_frontend::getCSS(); ?></style>
<script<?php echo consent_manager_frontend::getNonceAttribute(); ?>>
<?php echo consent_manager_frontend::getJS(); ?>
</script>
<?php echo consent_manager_frontend::getBox(); ?>
<?php
// Mit custom Fragment
echo consent_manager_frontend::getFragment(0, 0, 'my_custom_box.php');
// Mit Inline-Modus
echo consent_manager_frontend::getFragmentWithVars(0, 0, 'consent_manager_box_cssjs.php', ['inline' => true]);
?>Für Inline-Blocker (YouTube, Vimeo, Google Maps, etc.) müssen zusätzliche Assets geladen werden:
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title><?= rex_article::getCurrent()->getName() ?></title>
<!-- Consent Manager Inline CSS (für Blocker-Platzhalter) -->
<link rel="stylesheet" href="<?= rex_url::addonAssets('consent_manager', 'consent_inline.css') ?>">
<!-- Optional: Vidstack CSS (nur wenn Vidstack installiert) -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<link rel="stylesheet" href="<?= rex_url::addonAssets('vidstack', 'vidstack.css') ?>">
<?php endif; ?>
</head>
<body>
<?php
// Hauptinhalt mit automatischer oEmbed-Umwandlung
echo rex_article::getCurrent()->getArticle();
?>
<!-- Consent Manager Inline JavaScript (WICHTIG für Button-Funktionalität!) -->
<script defer src="<?= rex_url::addonAssets('consent_manager', 'consent_inline.js') ?>"></script>
<!-- Optional: Vidstack JavaScript (nur wenn Vidstack installiert) -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack.js') ?>"></script>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack_helper.js') ?>"></script>
<?php endif; ?>
</body>
</html>Was wird benötigt:
| Asset | Wofür? | Zwingend? |
|---|---|---|
consent_inline.css |
Styling der Inline-Blocker (Thumbnails, Buttons, Overlay) | ✅ Ja |
consent_inline.js |
Button-Funktionalität ("Einmal laden", "Einstellungen") | ✅ Ja |
vidstack.css |
Styling für Vidstack Player (nur bei player_mode: vidstack) |
Optional |
vidstack.js |
Vidstack Player Funktionalität | Optional |
- Inline-Blocker werden nicht korrekt dargestellt
- Buttons funktionieren nicht ("Einmal laden" macht nichts)
- Videos laden nicht nach Consent-Klick
- CKE5 oEmbed-Tags werden nicht umgewandelt
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= rex_article::getCurrent()->getName() ?></title>
<!-- Consent Manager Inline CSS -->
<link rel="stylesheet" href="<?= rex_url::addonAssets('consent_manager', 'consent_inline.css') ?>">
<!-- Optional: Vidstack CSS -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<link rel="stylesheet" href="<?= rex_url::addonAssets('vidstack', 'vidstack.css') ?>">
<?php endif; ?>
<!-- Dein eigenes CSS -->
<link rel="stylesheet" href="<?= rex_url::base('assets/css/styles.css') ?>">
</head>
<body>
<?php
// Consent Manager Box (globales Cookie-Banner)
echo consent_manager_frontend::getFragment(0, 0, 'consent_manager_box_cssjs.php');
// Hauptinhalt mit automatischer oEmbed-Umwandlung
echo rex_article::getCurrent()->getArticle();
?>
<!-- Consent Manager Inline JavaScript (für Blocker-Buttons) -->
<script defer src="<?= rex_url::addonAssets('consent_manager', 'consent_inline.js') ?>"></script>
<!-- Optional: Vidstack JavaScript -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack.js') ?>"></script>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack_helper.js') ?>"></script>
<?php endif; ?>
<!-- Dein eigenes JavaScript -->
<script defer src="<?= rex_url::base('assets/js/scripts.js') ?>"></script>
</body>
</html>Verfügbare Parameter:
| Parameter | Standard | Beschreibung |
|---|---|---|
forceCache |
0 im Frontend, 1 im Backend |
Cache-Steuerung: 0 = Cache verwenden, 1 = Cache neu generieren |
forceReload |
0 wenn cache Parameter gesetzt, sonst 1 |
Reload-Steuerung der Consent-Box |
fragment |
consent_manager_box_cssjs.php |
Custom Fragment-Template-Datei |
vars (Array) |
[] |
Zusätzliche Variablen (z.B. ['inline' => true]) |
REX_CONSENT_MANAGER Variable (alternativ):
REX_CONSENT_MANAGER[]
REX_CONSENT_MANAGER[forceCache=0 forceReload=0]
REX_CONSENT_MANAGER[inline=true]
REX_CONSENT_MANAGER[fragment=my_custom_box.php]Platzierung:
- Im
<head>-Bereich oder vor</body>(empfohlen für Performance) - Für Inline-Consent-Modus:
['inline' => true]als Parameter übergeben
Empfohlene Integration:
- Footer-Link: Platzieren Sie einen dauerhaften Link im Website-Footer
- Datenschutz-Seite: Verlinken Sie aus der Datenschutzerklärung
- Barrierefreiheit: Der Link sollte immer erreichbar sein
HTML-Link:
<a class="consent_manager-show-box">Datenschutz-Einstellungen</a>Mit automatischem Reload:
<a class="consent_manager-show-box-reload">Datenschutz-Einstellungen</a>JavaScript-Aufruf:
consent_manager_showBox();Beispiel Footer-Integration:
<footer>
<div class="footer-links">
<a href="/impressum/">Impressum</a>
<a href="/datenschutz/">Datenschutz</a>
<a class="consent_manager-show-box">Cookie-Einstellungen</a>
</div>
</footer>JavaScript:
if (consent_manager_hasconsent('youtube')) {
// YouTube wurde akzeptiert
}PHP:
<?php
if (consent_manager_util::has_consent('youtube')) {
// YouTube wurde akzeptiert
}
?>Jede Domain der REDAXO-Instanz muss einzeln konfiguriert werden:
- Domain ohne Protokoll hinterlegen (z.B.
www.beispiel.de) - Datenschutzerklärung und Impressum je Domain
- Automatischer Abgleich mit
$_SERVER['HTTP_HOST']
Google Consent Mode v2 Integration:
- Pro Domain aktivierbar
- GDPR-konforme Standard-Einstellungen
- Automatische Script-Integration
- Debug-Konsole verfügbar
Jeder externe Dienst (Analytics, Social Media, etc.) wird einzeln angelegt:
Schlüssel: Interne Bezeichnung ohne Sonderzeichen Dienstname: Wird in der Consent-Box angezeigt Cookie-Definitionen: YAML-Format für Cookie-Details
Konfigurierbare Cookie-Sicherheit (seit Version 4.5.0):
Der Consent Manager unterstützt konfigurierbare Cookie-Einstellungen für maximale Sicherheit:
Standardwerte:
cookie_samesite: 'Lax' # Standard für gute Kompatibilität
cookie_secure: false # false für HTTP-SeitenEmpfohlene Werte für HTTPS-Seiten:
cookie_samesite: 'Strict' # Maximale Sicherheit
cookie_secure: true # Nur über HTTPS übertragenSameSite Optionen:
Strict: Cookies werden nur bei direktem Besuch der Domain gesendet (höchste Sicherheit)Lax: Cookies werden auch bei Top-Level-Navigation gesendet (Standard, guter Kompromiss)None: Cookies werden immer gesendet (⚠️ erfordertsecure: true)
Secure Flag:
true: Cookie wird nur über HTTPS übertragen (empfohlen für Produktiv-Sites)false: Cookie wird auch über HTTP übertragen (nur für Entwicklung)
Konfiguration in package.yml:
cookie_samesite: 'Strict'
cookie_secure: trueexample.comundshop.example.comsind separate Domains- Consent muss für jede Domain einzeln eingeholt werden
- Cookie gilt nur für die exakte Domain, nicht für Subdomains
Das AddOn verwendet YAML-Format für die Definition von Cookie-Details:
Beispiel Cookie-Definition:
-
name: _ga
time: "2 Jahre"
desc: "Speichert für jeden Besucher eine anonyme ID für die Zuordnung von Seitenaufrufen."
-
name: _gat
time: "1 Tag"
desc: "Verhindert zu schnelle Datenübertragung an Analytics-Server."JavaScript-Integration:
<script>
// Wird geladen, wenn Nutzer zustimmt
gtag('config', 'GA_MEASUREMENT_ID');
</script>Dienste werden in Gruppen zusammengefasst, die einzeln akzeptiert werden können:
| Einstellung | Beschreibung |
|---|---|
| Schlüssel | Interne Bezeichnung ohne Sonderzeichen |
| Technisch notwendig | Gruppe ist immer aktiv und nicht deaktivierbar |
| Domain | Zuordnung zur entsprechenden Domain |
| Name | Anzeigename für Website-Besucher |
| Beschreibung | Erklärung der Gruppe |
| Dienste | Zugewiesene Services |
Das AddOn bietet verschiedene vorgefertigte Themes:
Verfügbare Themes:
- Standard-Themes (Hell, Dunkel, Bottom Bar, Bottom Right)
- Community-Themes (Olien Dark/Light, Skerbis Glass, XOrange)
- 🆕 Accessibility Theme (
consent_manager_frontend_a11y.css) - Barrierefrei optimiert
Eigenes Theme erstellen:
- Bestehendes Theme kopieren
- In
/project/consent_manager_themes/ablegen - Dateiname:
consent_manager_frontend_theme_*.scss - Anpassungen vornehmen
- In Theme-Vorschau auswählen
Theme-Vorschau testen:
/redaxo/index.php?page=consent_manager/theme&preview=project:consent_manager_frontend_mein_theme.scss
Issues #326, #304 - Optimierungen für Barrierefreiheit:
Das neue A11y-Theme (consent_manager_frontend_a11y.scss) bietet umfassende Barrierefreiheit:
WCAG 2.1 AA Konformität:
- ✅ Kontrastverhältnisse: 4.5:1 für Text, 3:1 für UI-Komponenten
- ✅ Focus-Indikatoren: 3px blaue Umrandung für alle interaktiven Elemente
- ✅ Touch-Targets: Mindestens 44x44px für alle Buttons und Links
- ✅ Screen Reader: Korrekte ARIA-Attribute (Issue #304)
role="dialog"nur auf consent_manager-wrapperaria-modal="true"für modalen Dialogaria-labelledbyverknüpft mit Überschriftaria-hiddendynamisch bei Öffnen/Schließen
- ✅ Tastatursteuerung: Vollständige Navigation ohne Maus möglich
- ✅ Focus Trap: Tab-Navigation bleibt innerhalb des Modals
- ✅ DSGVO-konform: Alle 3 Buttons (ablehnen/auswählen/alle) visuell gleichwertig
Modales Verhalten (Issue #326):
- Auto-Focus: Beim Öffnen wird automatisch der erste Button fokussiert
- Focus Trap: Tab/Shift+Tab bleiben innerhalb des Consent-Dialogs
- ESC funktioniert immer: Schließt Dialog von jedem Element aus
- Tastatur-Zugänglichkeit: Kein Entkommen nur mit Maus nötig
- ARIA-Management: Hintergrund-Container ist für Screen Reader unsichtbar (Issue #304)
Tastatursteuerung:
ESC → Consent Box schließen (von überall im Dialog)
Tab → Vorwärts zwischen Elementen navigieren (bleibt im Dialog)
Shift+Tab → Rückwärts zwischen Elementen navigieren (bleibt im Dialog)
Enter / Space → Details ein-/ausklappen
Enter → Buttons aktivieren
Theme-Varianten:
- Accessibility (WCAG 2.1 AA) - Neutrales Grau, DSGVO-konforme Buttons
- Accessibility Blue - Blauer Akzent (#0066cc)
- Accessibility Green - Grüner Akzent (#025335)
- Accessibility Compact - Platzsparende Version, Grau
- Accessibility Compact Blue - Platzsparend mit blauem Akzent Enter / Space → Details ein-/ausklappen (Issue #326) Enter → Buttons aktivieren
**Implementierte Features:**
- **ESC-Taste:** Schließt die Consent Box ohne durch alle Felder zu tabben
- **Space-Taste:** Aktiviert den "Details anzeigen"-Button (zusätzlich zu Enter)
- **aria-expanded:** Zeigt Screen Readern den Zustand des Details-Bereichs
- **Reduzierte Bewegung:** Respektiert `prefers-reduced-motion` Einstellung
- **Hoher Kontrast:** Unterstützt `prefers-contrast: high` Modus
- **Focus-Management:** Automatischer Focus auf erste Checkbox beim Öffnen
**Verwendung:**
```php
<!-- Im Backend: Theme auf "consent_manager_frontend_a11y.css" setzen -->
<!-- Oder manuell: -->
<link rel="stylesheet" href="/assets/addons/consent_manager/consent_manager_frontend_a11y.css">
Zusätzliche Empfehlungen:
- Platzieren Sie den Cookie-Einstellungs-Link prominent im Footer
- Verwenden Sie beschreibende Linktexte (z.B. "Cookie-Einstellungen" statt "Klick hier")
- Testen Sie mit Screen Readern (NVDA, JAWS, VoiceOver)
- Prüfen Sie Keyboard-Navigation regelmäßig
Fragment anpassen:
- Standard:
/redaxo/src/addons/consent_manager/fragments/consent_manager_box.php - Eigenes Fragment:
/theme/private/fragments/consent_manager_box.php
CSS-Ausgabe steuern:
- Standardmäßig wird
consent_manager_frontend.cssausgegeben - Über Einstellungen deaktivierbar für eigene CSS-Implementierung
Der Consent Manager bietet drei Implementierungswege für Google Consent Mode v2:
Google Consent Mode wird nicht verwendet - Standard GDPR-Verhalten ohne gtag-Integration.
Domain-Aktivierung:
- In Domains → Google Consent Mode v2 auf "Automatisch (Auto-Mapping)" setzen
- System erkennt automatisch Services und mappt sie zu Consent-Flags
- Keine manuelle Programmierung erforderlich
Debug-Konsole für Entwickler:
Domain-Konfiguration → Debug-Modus "Aktiviert"
- Domain-Konfiguration: Debug-Modus in Domain-Einstellungen aktivieren
- Backend-Login erforderlich: Nur für angemeldete Administrator sichtbar
Automatische Service-Mappings:
Google Analytics → analytics_storage
Google Tag Manager → analytics_storage, ad_storage, ad_user_data, ad_personalization
Google Ads → ad_storage, ad_user_data, ad_personalization
Facebook Pixel → ad_storage, ad_user_data, ad_personalization
YouTube → ad_storage, personalization_storage
Google Maps → functionality_storage, personalization_storage
Matomo/Hotjar → analytics_storage
Service-Schlüssel für automatische Erkennung: Die automatische Erkennung funktioniert über den Service-Schlüssel (UID). Verwende diese Schlüssel:
| Service | Empfohlener Schlüssel | Alternative |
|---|---|---|
| Google Analytics | google-analytics |
analytics, ga |
| Google Tag Manager | google-tag-manager |
gtm, tag-manager |
| Google Ads | google-ads |
adwords, google-adwords |
| Facebook Pixel | facebook-pixel |
facebook, meta-pixel |
| YouTube | youtube |
yt |
| Google Maps | google-maps |
maps, gmaps |
| Matomo | matomo |
piwik |
| Hotjar | hotjar |
- |
| Microsoft Clarity | microsoft-clarity |
clarity |
🔧 Flexible UID-Struktur (Multidomain/Multilanguage):
Das Auto-Mapping funktioniert mit Partial String Matching - Suffixes sind erlaubt:
✅ Funktioniert perfekt:
google-analytics → Erkannt als Google Analytics
google-analytics-shop → Erkannt als Google Analytics
google-analytics-de → Erkannt als Google Analytics
facebook-pixel-checkout → Erkannt als Facebook Pixel
matomo-staging → Erkannt als Matomo
youtube-embeds → Erkannt als YouTube
❌ Funktioniert NICHT:
shop-google-analytics → NICHT erkannt (Prefix stört)
custom-analytics → NICHT erkannt (fehlt "google-analytics")
💡 Empfehlung für Multidomain/Multilanguage:
google-analytics-de,google-analytics-shop,google-analytics-enfacebook-pixel-landing,facebook-pixel-checkoutmatomo-domain1,matomo-domain2youtube-videos-de,youtube-videos-en
Beispiel Service-Anlage:
- Dienste → Service hinzufügen
- Schlüssel:
google-tag-manager⭐ - Dienstname:
Google Tag Manager - Scripts: Dein GTM-Code
- Gruppe zuweisen: z.B. "Marketing"
➡️ System erkennt automatisch "google-tag-manager" und mappt zu analytics_storage, ad_storage, etc.
Funktionsweise:
- System generiert automatisch
gtag('consent', 'default', {...})mit GDPR-konformen Defaults (alle 'denied') - Bei Consent-Änderungen wird automatisch
gtag('consent', 'update', {...})aufgerufen - Services werden basierend auf UID/Namen automatisch erkannt und gemappt
Eigene gtag-Integration in Service-Scripts:
<script>
// Google Consent Mode wird initialisiert, aber Service-Scripts müssen
// gtag('consent', 'update') selbst implementieren
gtag('consent', 'update', {
'analytics_storage': 'granted'
});
</script>GDPR-konforme Standard-Einstellungen:
analytics_storage: deniedad_storage: deniedad_user_data: deniedad_personalization: deniedfunctionality_storage: deniedsecurity_storage: deniedpersonalization_storage: denied
Debug-Konsole zeigt:
- 🎯 Google Consent Mode v2 Status: Aktueller Modus (Deaktiviert/Automatisch/Manuell)
- Consent-Status: Alle gtag-Flags mit aktuellen Werten
- Service-Übersicht: Erkannte Services und deren Zuordnung
- Cookie-Analyse: Detaillierte Cookie-Informationen
- localStorage: Consent-Daten-Speicherung
Aktivierung Debug-Konsole:
?debug_consent=1
Vorteile automatischer Modus:
- ✅ Keine Programmierung erforderlich
- ✅ Automatische Service-Erkennung
- ✅ GDPR-konforme Defaults
- ✅ Wartungsfreie Updates
- ✅ Debug-Konsole für Troubleshooting
Eingabe-Modul mit MForm:
<?php
$mform = new mform();
$cookies = [];
$qry = 'SELECT uid,service_name FROM '.rex::getTable('consent_manager_cookie').' WHERE clang_id = '.rex_clang::getCurrentId();
foreach (rex_sql::factory()->getArray($qry) as $v) {
if ($v['uid'] == 'consent_manager') continue;
$cookies[$v['uid']] = $v['service_name'];
}
$mform->addSelectField(1);
$mform->setOptions($cookies);
$mform->setLabel('Dienst');
echo $mform->show();
?>Template-Integration:
REX_COOKIEDB[]Zeigt alle gesetzten Cookies und die Einwilligungshistorie an.
Aktivierung:
- Domain-Konfiguration: In Domains → Debug-Modus auf "Aktiviert" setzen
- REDAXO Debug-Modus:
rex::isDebugMode()(automatisch aktiv) - Backend-Login erforderlich: Nur für angemeldete Backend-Benutzer
Debug-Konsole zeigt:
- Consent-Status und Default-Werte
- Service-Konfiguration
- Cookie-Details
- Browser-Storage-Inhalte
- Google Consent Mode Status
Consent-Box wird nicht angezeigt:
- Domain korrekt hinterlegt und in Cookie-Gruppe zugeordnet?
- Domain-Übereinstimmung prüfen (
www.vs. ohne) - Template-Platzhalter im
<head>-Bereich? - Eigenes CSS aktiviert aber nicht eingebunden?
Cookies angezeigt, Scripts nicht geladen:
- Scripts in entsprechendem Service hinterlegt?
<script>-Tags vollständig vorhanden?- Consent tatsächlich erteilt?
Seite ohne Consent-Box: Token in Einstellungen definieren und URL-Parameter verwenden:
https://beispiel.de/seite.html?skip_consent=MEINTOKEN
CSP (Content Security Policy) Kompatibilität: ✅ Gelöst ab Version 4.5.0: Das Consent-Manager AddOn ist jetzt CSP-kompatibel!
Implementierte Lösung:
- Automatische Nonce-Übergabe: Nonce wird automatisch von
rex_response::getNonce()geholt - Keine manuelle Konfiguration nötig: Funktioniert out-of-the-box
- Kein innerHTML mehr: Scripts werden via
document.createElement()undtextContenteingefügt - CSP-freundlich: Kompatibel mit
script-src 'nonce-XXX'Policies
CSP-Header Beispiel:
Content-Security-Policy: script-src 'self' 'nonce-ZUFÄLLIGER_NONCE';
Einfache Verwendung im Template:
<?php
// Einfach aufrufen - Nonce wird automatisch verwendet!
echo consent_manager_frontend::getFragment(0, 0, 'consent_manager_box_cssjs.php');
?>Manuelle CSP-Header setzen (optional):
<?php
// Nur wenn du eigene CSP-Header setzen möchtest
$nonce = rex_response::getNonce();
header("Content-Security-Policy: script-src 'self' 'nonce-{$nonce}'");
echo consent_manager_frontend::getFragment(0, 0, 'consent_manager_box_cssjs.php');
?>Externe Scripts bevorzugen:
Für maximale CSP-Kompatibilität externe Scripts mit src Attribut verwenden:
// ✅ Empfohlen: Externe Script-Dateien
<script src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
// ⚠️ Weniger CSP-freundlich: Inline-Scripts
<script>
gtag('config', 'GA_MEASUREMENT_ID');
</script>Hinweis zu Issue #320: Das ursprünglich gemeldete Problem mit dynamischen Script-Injektionen ist behoben. Die Lösung verwendet:
createElement()stattinnerHTMLtextContentstattinnerHTMLfür Script-Content- Automatische Nonce-Propagierung
- Anhängen an
document.bodystatt versteckte Container
Subdomain-Probleme und DSGVO-Konformität: ✅ Gelöst ab Version 4.5.0: Subdomain-spezifische Consent-Verwaltung (Issue #317)
Problem:
- Alte Versionen verwendeten Wildcard-Cookies (
.example.com) - Consent von
example.comgalt fälschlicherweise auch fürshop.example.com - DSGVO-Verstoß: Consent muss domain-spezifisch sein!
Lösung:
- Domain-spezifische Cookies: Jede (Sub-)Domain erhält eigenen Consent
- Keine Wildcard-Domains: Cookie gilt nur für exakte Domain
- Korrekte Subdomain-Erkennung:
shop.example.comwird als vollständige Domain behandelt
Empfehlung für HTTPS-Seiten:
// In package.yml oder Einstellungen:
cookie_samesite: 'Strict' # Empfohlen für HTTPS
cookie_secure: true # Nur über HTTPS übertragenWichtig für Multi-Domain-Setups:
- Jede Domain benötigt eigene Consent-Manager Konfiguration
example.comundshop.example.comsind DSGVO-rechtlich separate Websites- Consent muss für jede Domain einzeln eingeholt werden
Vollzugriff für Redakteure:
- Recht
consent_manager[]zuweisen - Zusätzlich
consent_manager[editor]zuweisen - Zugriff auf alle Funktionen (Domains, Services, Gruppen, Texte, Konfiguration)
Nur Text-Bearbeitung erlauben:
- Recht
consent_manager[]zuweisen - Zusätzlich
consent_manager[texteditonly]zuweisen - Nur Zugriff auf Texte (eingeschränkter Modus)
Administratoren:
- Haben immer vollen Zugriff auf alle Funktionen
Automatische Übertragung:
- Inhalte der Startsprache werden automatisch in neue Sprachen übertragen
- Nachträgliche Anpassung möglich
Sprachspezifische Felder:
- Texte und Beschreibungen individuell anpassbar
- Schlüssel, Scripts und Domains nur in Startsprache änderbar
Der Consent Manager triggert mehrere JavaScript-Events für Custom-Integrationen:
Verf\u00fcgbare Events:
consent_manager-show- Box wurde ge\u00f6ffnetconsent_manager-close- Box wurde geschlossenconsent_manager-saved- Consent wurde gespeichert (enth\u00e4lt Consent-Daten)
JavaScript Event-Listener:
// Box wurde ge\u00f6ffnet
document.addEventListener('consent_manager-show', function() {
console.log('Consent Box ge\u00f6ffnet');
// Custom Analytics-Tracking
// Custom Overlays/Animations
});
// Box wurde geschlossen
document.addEventListener('consent_manager-close', function() {
console.log('Consent Box geschlossen');
// Cleanup-Aktionen
});
// Consent wurde gespeichert
document.addEventListener('consent_manager-saved', function(e) {
var consents = JSON.parse(e.detail);
console.log('Gespeicherte Consents:', consents);
// Verarbeitung der Consent-Daten
// z.B. Analytics, Tag Manager Updates
});Praktische Beispiele:
// A/B-Testing: Tracking welche Nutzer Consent-Box sehen
document.addEventListener('consent_manager-show', function() {
if (typeof gtag !== 'undefined') {
gtag('event', 'consent_box_shown');
}
});
// Custom Animation beim Schließen
document.addEventListener('consent_manager-close', function() {
document.body.classList.add('consent-box-closed');
});
// Conditional Script Loading basierend auf Consent
document.addEventListener('consent_manager-saved', function(e) {
var consents = JSON.parse(e.detail);
if (consents.includes('google-analytics')) {
// Google Analytics wurde akzeptiert
console.log('Analytics aktiviert');
}
if (consents.includes('marketing')) {
// Marketing-Cookies wurden akzeptiert
console.log('Marketing aktiviert');
}
});// Consent-Status prüfen
consent_manager_util::has_consent('service_key');
// Frontend-Instanz erstellen
$consent_manager = new consent_manager_frontend();
$consent_manager->setDomain($_SERVER['HTTP_HOST']);Beim ersten Aufruf der Konfiguration wird ein 7-stufiger Quickstart-Assistent angezeigt:
- Willkommen - Übersicht über das Setup
- Domain konfigurieren - Website-Domain hinterlegen
- Services wählen - Zwischen Minimal- und Standard-Setup entscheiden
- Gruppen - Cookie-Gruppen verwalten
- Texte - Frontend-Texte anpassen
- Design - Theme auswählen
- Testen - Frontend-Integration testen
Mehrsprachig: Der Assistent ist vollständig in Deutsch und Englisch verfügbar.
Das neue JSON-basierte Setup-System ersetzt das alte SQL-Format und bietet:
Vorteile:
- ✅ Bessere Versionskontrolle und Nachvollziehbarkeit
- ✅ Einfacher Export/Import von Konfigurationen
- ✅ Strukturierte Datenhaltung
- ✅ Flexible Anpassung an individuelle Bedürfnisse
Minimal-Setup: Grundkonfiguration mit nur essentiellem Service
- Domain-Gruppe "Technisch notwendig"
- Basic Consent Manager Service
- Ideal für datenschutz-minimale Websites
Standard-Setup: Vollständige Service-Sammlung (
- Alle gängigen Services vorkonfiguriert
- Strukturierte Cookie-Gruppen
- Ready-to-use für die meisten Websites
Export der aktuellen Konfiguration:
Configuration → Export aktuelle Konfiguration → JSON-Datei herunterladen
Import einer JSON-Konfiguration:
Configuration → JSON-Datei hochladen → Import bestätigen
Das Standard-Setup enthält eine umfangreiche Sammlung mit 25 vorkonfigurierten Services für moderne Websites, darunter gängige Dienste wie beispielsweise Google Analytics, Facebook Pixel, YouTube, Google Maps, Matomo, HubSpot, WhatsApp Business, LinkedIn, TikTok, Pinterest, Booking.com und viele weitere.
Die Services sind bereits strukturiert in Kategorien wie Analytics, Marketing, externe Medien, Kommunikation und technisch notwendige Dienste organisiert.
- API-Keys ersetzen: Alle Platzhalter müssen durch echte IDs/Keys ersetzt werden
- Rechtliche Prüfung: Cookie-Beschreibungen und Datenschutzlinks sollten von Datenschutzbeauftragten oder der Rechtsabteilung geprüft werden
- Aktualität: Dienste-Definitionen entsprechen dem aktuellen Stand der Datenschutzbestimmungen
Seit Version 5.x stehen separate Methoden für CSS, JavaScript und Box-HTML zur Verfügung:
consent_manager_frontend::getCSS()
<?php
// Gibt nur das CSS zurück
$css = consent_manager_frontend::getCSS();
echo '<style>' . $css . '</style>';
?>- Return: CSS-String mit Theme-Unterstützung
- Use Case: Inline-CSS oder separate CSS-Datei generieren
- Performance: Cached durch REDAXO
consent_manager_frontend::getJS()
<?php
// Gibt JavaScript inkl. Parameter und Box-Template zurück
$js = consent_manager_frontend::getJS();
?>
<script<?php echo consent_manager_frontend::getNonceAttribute(); ?>>
<?php echo $js; ?>
</script>- Return: Vollständiges JavaScript (js.cookie, polyfills, consent_manager_frontend.js)
- Enthält: Parameter, Box-Template, Cookie-Expiration
- CSP: Nonce-Attribut automatisch über
getNonceAttribute()verfügbar - Use Case: Inline-JavaScript oder separate JS-Datei
consent_manager_frontend::getBox()
<?php
// Gibt nur das Box-HTML zurück (ohne CSS/JS)
echo consent_manager_frontend::getBox();
?>- Return: HTML der Consent-Box
- Use Case: AJAX-Loading, Custom Integration, SPA-Frameworks
- Voraussetzung: CSS und JS müssen separat geladen sein
consent_manager_frontend::getNonceAttribute()
<?php
// CSP-Nonce-Attribut für Script-Tags
?>
<script<?php echo consent_manager_frontend::getNonceAttribute(); ?>>
// Ihr JavaScript-Code
</script>- Return:
nonce="XXX"oder leerer String - CSP: Automatische Integration mit REDAXO's CSP-Nonce
- Use Case: Inline-Scripts mit Content Security Policy
Anwendungsbeispiele:
<?php
// Beispiel 1: Alles inline im Template
?>
<style><?php echo consent_manager_frontend::getCSS(); ?></style>
<?php echo consent_manager_frontend::getBox(); ?>
<script<?php echo consent_manager_frontend::getNonceAttribute(); ?>>
<?php echo consent_manager_frontend::getJS(); ?>
</script>
<?php
// Beispiel 2: JavaScript in separate Datei schreiben
$jsFile = rex_path::assets('consent_manager_custom.js');
rex_file::put($jsFile, consent_manager_frontend::getJS());
?>
<script src="<?php echo rex_url::assets('consent_manager_custom.js'); ?>"<?php echo consent_manager_frontend::getNonceAttribute(); ?>></script>
<?php
// Beispiel 3: Für AJAX/SPA nur Box-HTML zurückgeben
if (rex_request::isAjaxRequest()) {
rex_response::sendJson([
'html' => consent_manager_frontend::getBox(),
'css' => consent_manager_frontend::getCSS()
]);
exit;
}
?><?php
$arr = json_decode($_COOKIE['consent_manager'], true);
$consents = $arr ? array_flip($arr['consents']) : [];
if (isset($consents['google-maps'])) {
// Google Maps laden
echo '<div id="google-maps"></div>';
} else {
// Platzhalter mit Consent-Link anzeigen
echo '<div>Für Google Maps müssen Cookies akzeptiert werden.</div>';
echo '<a class="consent_manager-show-box-reload">Cookie-Einstellungen</a>';
}
?>// Prüfung vor AJAX-Request
function loadExternalContent() {
if (consent_manager_hasconsent('external-api')) {
$.ajax({
url: '/api/external-data',
success: function(data) {
// Daten verarbeiten
}
});
}
}Neu: Consent nur bei Bedarf - perfekt für Seiten mit wenigen externen Inhalten.
Problem: Sie haben 400 Artikel, aber nur 2 brauchen YouTube-Videos. Normale Consent-Banner nerven alle Besucher, obwohl 99% nie Videos sehen.
Lösung: Inline-Consent zeigt Platzhalter statt Videos. Consent-Dialog erscheint erst beim Klick auf "Video laden".
Template-Integration ZWINGEND erforderlich:
Die folgenden Assets müssen im Template eingebunden sein, damit Inline-Blocker funktionieren:
<!-- Im <head> -->
<link rel="stylesheet" href="<?= rex_url::addonAssets('consent_manager', 'consent_inline.css') ?>">
<!-- Vor </body> -->
<script defer src="<?= rex_url::addonAssets('consent_manager', 'consent_inline.js') ?>"></script>Optional für Vidstack Player (moderne Video-Wiedergabe):
<!-- Im <head> -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<link rel="stylesheet" href="<?= rex_url::addonAssets('vidstack', 'vidstack.css') ?>">
<?php endif; ?>
<!-- Vor </body> -->
<?php if (rex_addon::exists('vidstack') && rex_addon::get('vidstack')->isAvailable()): ?>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack.js') ?>"></script>
<script defer src="<?= rex_url::addonAssets('vidstack', 'vidstack_helper.js') ?>"></script>
<?php endif; ?>- ❌ Buttons nicht ("Einmal laden", "Einstellungen")
- ❌ Videos laden nicht nach Consent
- ❌ CKE5 oEmbed nicht automatisch umgewandelt
- ❌ Styling fehlt (keine Thumbnails, kein Overlay)
Automatische Umwandlung von oEmbed-Tags:
<!-- Redakteur fügt in CKE5 ein: -->
<oembed url="https://www.youtube.com/watch?v=dQw4w9WgXcQ"></oembed>
<!-- Frontend zeigt automatisch: -->
<!-- ┌─────────────────────────────────┐ -->
<!-- │ 📺 Video-Thumbnail │ -->
<!-- │ YouTube Video │ -->
<!-- │ Für Anzeige werden Cookies... │ -->
<!-- │ [Einmal laden] [Einstellungen] │ -->
<!-- └─────────────────────────────────┘ -->Unterstützte Plattformen:
- ✅ YouTube (alle URL-Formate)
- ✅ Vimeo (alle URL-Formate)
Services konfigurieren:
Backend → Consent Manager → Dienste:
-
YouTube Service:
- UID:
youtube - Service-Name: YouTube
- Datenschutz:
https://policies.google.com/privacy
- UID:
-
Vimeo Service:
- UID:
vimeo - Service-Name: Vimeo
- Datenschutz:
https://vimeo.com/privacy
- UID:
Player-Modi (Backend → Domains):
| Modus | Beschreibung |
|---|---|
auto |
Vidstack wenn verfügbar, sonst native iframe (Standard) |
vidstack |
Immer Vidstack Player (moderne UI, Accessibility) |
native |
Immer Standard YouTube/Vimeo iframe |
Vorteile Vidstack Player:
- ✅ Moderne, anpassbare Player-UI
- ✅ Kleinere Dateigröße als YouTube iframe
- ✅ Vollständige Accessibility (WCAG 2.1)
- ✅ Touch-optimiert
- ✅ Konsistente UI über alle Plattformen
Medienspezifischer Consent:
- ✅ Inline-Consent aktiviert NUR das angeklickte Medium
- ✅ Jedes Video/Embed wird einzeln freigeschaltet
- ✅ Keine globale Aktivierung aller Services einer Gruppe
- ✅ Maximaler Datenschutz durch minimale Consent-Erteilung
Beispiel: Nutzer klickt "YouTube Video laden" → Nur dieses eine Video wird geladen, andere YouTube-Videos auf der Seite bleiben gesperrt.
Globale Aktivierung über "Alle Einstellungen":
- Der Button "Alle Einstellungen" (früher "Cookie-Details") öffnet das vollständige Consent Manager Fenster
- Dort kann der Nutzer alle Services einer Gruppe global aktivieren
- Wichtig: Button-Text ist über die Texte-Verwaltung vollständig anpassbar und übersetzbar
<?php
// Template/Modul - statt direktem iframe
echo doConsent('youtube', 'dQw4w9WgXcQ', [
'title' => 'Rick Astley - Never Gonna Give You Up',
'width' => 560,
'height' => 315
]);
// Funktioniert auch mit kompletten URLs
echo doConsent('youtube', 'https://www.youtube.com/watch?v=dQw4w9WgXcQ', [
'title' => 'Mein Video'
]);
// Mit custom Attributen (z.B. für UIkit, Bootstrap, etc.)
echo doConsent('youtube', 'dQw4w9WgXcQ', [
'title' => 'Responsive YouTube Video',
'width' => 560,
'height' => 315,
'attributes' => [
'class' => 'uk-responsive-width',
'data-uk-video' => 'automute: true',
'data-uk-responsive' => ''
]
]);
?>✅ Automatische Privacy Policy Links:
- Services mit hinterlegter
provider_link_privacyzeigen automatisch den entsprechenden Datenschutz-Link - Format: "🔒 Datenschutzerklärung von [Anbieter]" (z.B. "🔒 Datenschutzerklärung von Google")
- Link öffnet in neuem Tab/Fenster
<?php
echo doConsent('google-maps', 'https://www.google.com/maps/embed?pb=!1m18!1m12...', [
'title' => 'Unsere Adresse',
'height' => 450
]);
?><?php
echo doConsent('vimeo', '123456789', [
'title' => 'Mein Vimeo Video',
'width' => 640,
'height' => 360
]);
// Oder mit URL
echo doConsent('vimeo', 'https://vimeo.com/123456789', [
'title' => 'Corporate Video'
]);
// Mit custom CSS Klassen und data-Attributen
echo doConsent('vimeo', '123456789', [
'title' => 'Corporate Video',
'attributes' => [
'class' => 'responsive-video my-custom-class',
'data-video-id' => '123456789',
'data-analytics' => 'tracked'
]
]);
?><?php
// Beliebige iframes
echo doConsent('custom-iframe', '<iframe src="https://example.com/widget"></iframe>', [
'title' => 'External Widget',
'privacy_notice' => 'Dieses Widget setzt Cookies für Funktionalität.'
]);
// JavaScript-Code
echo doConsent('google-analytics', '<script>gtag("config", "GA_MEASUREMENT_ID");</script>', [
'title' => 'Google Analytics',
'placeholder_text' => 'Analytics aktivieren'
]);
?>CSS/JS einbinden (einmalig im Template):
<?php echo rex_view::content('consent_manager_inline_cssjs.php'); ?>Oder manuell:
<!-- Im <head>-Bereich -->
<?php
if (class_exists('consent_manager_inline')) {
echo consent_manager_inline::getCSS();
echo consent_manager_inline::getJavaScript();
}
?>✅ Vollständige Integration:
- Nutzt bestehende Service-Konfiguration
- Automatisches Logging aller Consent-Aktionen
- "Alle Einstellungen"-Button öffnet vollständiges Consent Manager Fenster
- Bereits erteilte Consents werden respektiert
- DSGVO-konforme Dokumentation
- Button-Texte anpassbar: "Alle Einstellungen" kann über Texte-Verwaltung geändert werden (z.B. "Cookie-Einstellungen", "Datenschutz-Optionen", etc.)
- Privacy Policy Links: Automatische Anzeige von Datenschutzerklärungen der Service-Anbieter
- Keine Confirm-Alerts: Direkte Consent-Aktivierung ohne störende Browser-Dialoge
✅ Smart Service Detection:
- YouTube: Automatische Thumbnail-Generierung
- Vimeo: Professionelle Platzhalter
- Google Maps: Karten-Icon und Hinweise
- Generic: Universell für alle anderen Services
✅ User Experience:
- Responsive Design
- Smooth Animations
- Accessibility-konform
- Mobile-optimiert
- Vollständig übersetzbare Buttons über REDAXO Texte-Verwaltung
✅ Mehrsprachigkeit:
- Alle Button-Texte über Consent Manager → Texte anpassbar
- Automatische Sprachen-Synchronisation
- Individuelle Anpassung pro Sprache möglich
- Standard-Buttons: "Video laden", "Alle Einstellungen", "Datenschutz"
✅ Developer Experience:
- Ein
doConsent()für alle Services - Auto-Erkennung von Video-IDs aus URLs
- Flexible Optionen-Arrays
- Debug-Modus verfügbar
Der Inline-Consent generiert ansprechende Platzhalter:
<!-- YouTube-Platzhalter -->
<div class="consent-inline-placeholder">
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" />
<div class="consent-inline-overlay">
<div class="consent-inline-icon">🎥</div>
<h4>Rick Astley - Never Gonna Give You Up</h4>
<p>Für YouTube werden Cookies benötigt.</p>
<button onclick="...">YouTube Video laden</button>
<button onclick="...">Cookie-Details</button>
</div>
</div>| Global Consent | Inline Consent |
|---|---|
| ❌ Nervt alle Besucher | ✅ Nur bei tatsächlicher Nutzung |
| ❌ "Consent Fatigue" | ✅ Kontextuell und verständlich |
| ❌ Viele leere Zustimmungen | ✅ Bewusste Entscheidungen |
| ❌ Komplexe Setup für 2 Videos | ✅ Einfache Integration |
Perfect für:
- Blogs mit gelegentlichen Videos
- Corporate Sites mit einzelnen Maps
- Landing Pages mit gezielten Embeds
- Alle Seiten wo < 10% der Inhalte Consent brauchen
Consent-Debug-Panel: Seit Version 4.4.0 verfügbar für Entwickler und Troubleshooting.
Aktivierung:
?debug_consent=1
Features:
- Live-Anzeige aller Cookie-Stati
- Google Consent Mode Integration
- LocalStorage-Übersicht
- Service-Status-Monitor
- Neu: Inline-Consent-Tracking
MIT Lizenz - siehe LICENSE.md
Friends Of REDAXO: https://github.com/FriendsOfREDAXO
Projekt-Leads:
Contributors: Siehe GitHub
Danksagungen:
- Thomas Blum (Code aus Sprog AddOn)
- Thomas Skerbis (Testing und Spende)
- Peter Bickel (Entwicklungsspende)
- Oliver Kreischer (Cookie-Design)
Externe Bibliotheken:
- cookie.js - MIT Lizenz
Issue melden: GitHub Issues
Contributions: Pull Requests sind willkommen - besonders eigene Themes mit Screenshot oder Demo-Link!


