TL;DR
Seit März 2024 ist Google Consent Mode v2 für EWR/UK-Traffic Pflicht, wenn Sie Google Ads oder GA4 mit Remarketing nutzen — sonst verlieren Sie Conversion-Modellierung und Teile der Signale für Smart Bidding. In Next.js besteht die Implementierung aus drei Schichten: Standard „denied“ in gtag('consent', 'default', …) vor dem Laden der Tags, ein Banner, das die Nutzerwahl speichert (CookieBanner.tsx + localStorage), und gtag('consent', 'update', …) nach Akzeptanz der Kategorien Analyse/Marketing. Auf DevStudio.it laden GA4 (G-3HT7CZTN7P) und drei Ads-Container (AW-17557280025, AW-17769880693, AW-18151506857) in layout.tsx — das Banner in [locale]/layout.tsx speichert Präferenzen, muss aber mit Consent Mode verbunden werden, damit „Nur notwendige“ Werbesignale wirklich blockiert. Unten: Implementierung, DSGVO, Tests und typische Fehler.
Für wen das ist
- Betreiber von Unternehmensseiten mit Google Ads und GA4 in EU/UK
- Next.js-Entwickler, die CookieBanner mit
gtagintegrieren - Verantwortliche für DSGVO und Marketing-Performance zugleich
- Teams mit Conversion-Rückgang nach Cookie-Banner-Einführung
Suchbegriffe (SEO)
consent mode v2 google, consent mode ga4 nextjs, cookie banner dsgvo google ads, default denied consent mode, consent mode testen tag assistant
Was Consent Mode v2 ist
Consent Mode ist Googles Mechanismus, der Tags (gtag, GTM) den Einwilligungsstatus für Speicherung/Lesen von Cookies und Datenübermittlung an Google mitteilt. v2 (seit 2024 für Ads im EWR Pflicht) erweitert das Modell um Signale:
| Parameter | Bedeutung |
|---|---|
analytics_storage |
Analyse-Cookies (GA4) |
ad_storage |
Werbe-Cookies |
ad_user_data |
v2 — Nutzerdaten für Google-Werbung |
ad_personalization |
v2 — Werbepersonalisierung (Remarketing) |
Ohne v2 kann Google Remarketing, modellierte Conversions und Ads-Kontokonformität in der EU einschränken — auch wenn Tags technisch „auf der Seite“ sind.
Consent Mode ersetzt keinen Cookie-Banner — es ist die technische Schicht nach der Nutzerentscheidung (oder davor im Modus default denied).
Architektur auf Next.js — aktueller Stand
Im DevStudio.it-Projekt:
Tags in src/app/layout.tsx
- GA4
G-3HT7CZTN7P— StrategieafterInteractive(wichtig fürgenerate_leadbei schnellem Formular-Submit) - Google Ads — drei
AW--Container mitlazyOnload(LCP) - reCAPTCHA v3 — lazyOnload
GA4-Config enthält u.a. anonymize_ip: true und allow_ad_personalization_signals: false — guter DSGVO-Start, aber kein Ersatz für Consent Mode.
Banner in src/components/CookieBanner.tsx
Client-Komponente ('use client') in src/app/[locale]/layout.tsx:
- Nach 2 s prüft
localStorage.getItem('cookieConsent') - Alle akzeptieren →
analytics: true,marketing: true - Nur notwendige →
analytics: false,marketing: false - Präferenzen in
cookiePreferencesals JSON
Solides UX-Muster (verzögertes Banner, drei Buttons, Link zur Datenschutzerklärung). Fehlendes Produktionsstück: gtag('consent', 'update', …) synchron mit Buttons — ohne das leben localStorage und Google-Tags getrennt.
Default denied vs granted — was wählen
Default denied (empfohlen im EWR)
Vor Nutzerinteraktion sind alle Signale außer notwendigen verweigert:
gtag('consent', 'default', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500,
});Tags dürfen laden, senden aber cookieless Pings — Google modelliert Conversions statistisch. DSGVO-konform, wenn Banner informiert und echte Wahl bietet.
Default granted (riskant in der EU)
Alles „ja“ bis „Ablehnen“ — erfüllt in den meisten Aufsichtsbehörden-Interpretationen kein Opt-in. Nur außerhalb EWR oder mit ausdrücklicher juristischer Freigabe.
wait_for_update
wait_for_update: 500 (ms) gibt dem Banner Zeit für consent update vor dem ersten vollen Hit — reduziert Tracking-„Blitz“ vor Entscheidung.
Schritt-für-Schritt-Implementierung in Next.js 15
Schritt 1: Consent default vor GA4/Ads-Config
In layout.tsx, vor gtag('config', 'G-...'):
<Script id="google-consent-default" strategy="beforeInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
wait_for_update: 500,
region: ['AT','BE','BG','HR','CY','CZ','DK','EE','FI','FR','DE','GR','HU','IE','IT','LV','LT','LU','MT','NL','PL','PT','RO','SK','SI','ES','SE','IS','LI','NO','GB']
});
`}
</Script>region begrenzt striktes Default auf EWR+UK; außerhalb können Sie granted setzen (regionale Maps in einem Aufruf — siehe gtag-Doku).
Schritt 2: update in CookieBanner
Nach handleAcceptAll:
const grantAll = () => {
if (typeof window !== 'undefined' && window.gtag) {
window.gtag('consent', 'update', {
analytics_storage: 'granted',
ad_storage: 'granted',
ad_user_data: 'granted',
ad_personalization: 'granted',
});
}
localStorage.setItem('cookieConsent', 'accepted');
localStorage.setItem('cookiePreferences', JSON.stringify({
necessary: true, analytics: true, marketing: true,
}));
setIsVisible(false);
};Nach handleAcceptNecessary — update denied:
window.gtag?.('consent', 'update', {
analytics_storage: 'denied',
ad_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied',
});Schritt 3: Einwilligung nach Reload wiederherstellen
In CookieBanner useEffect — bei cookieConsent === 'accepted' cookiePreferences lesen und consent update bevor Banner erneut erscheint:
useEffect(() => {
const consent = localStorage.getItem('cookieConsent');
const prefsRaw = localStorage.getItem('cookiePreferences');
if (consent && prefsRaw) {
const prefs = JSON.parse(prefsRaw);
window.gtag?.('consent', 'update', {
analytics_storage: prefs.analytics ? 'granted' : 'denied',
ad_storage: prefs.marketing ? 'granted' : 'denied',
ad_user_data: prefs.marketing ? 'granted' : 'denied',
ad_personalization: prefs.marketing ? 'granted' : 'denied',
});
return;
}
const timer = setTimeout(() => setIsVisible(true), 2000);
return () => clearTimeout(timer);
}, []);Schritt 4: Ads lazy nur nach marketing granted (optional, strikte DSGVO)
Alternative: AW--Skripte gar nicht im Layout — dynamisch nach marketing: true injecten. Maximale Konformität, schwierigere Modellierung, Refactoring von layout.tsx. Consent Mode mit default denied + geladenen Tags ist der übliche Kompromiss mit ordentlichem Banner.
GA4 G-3HT7CZTN7P — Änderungen nach Consent Mode
Bei analytics_storage: 'denied':
- GA4 sendet cookieless Pings (Consent-Mode-Modellierung)
- Echtzeit-Berichte zeigen weniger Sitzungen bis Einwilligung
generate_leadnach Submit sollte nach granted ankommen — Formular nach „Alle akzeptieren“ testen
Bei GA4 afterInteractive muss default denied beforeInteractive sein, sonst erster page_view mit vollen Cookies.
GA4_MEASUREMENT_ID in src/lib/ga4-measurement-id.ts mit layout.tsx synchron halten.
Google Ads AW- — drei Container und Conversions
Drei Ads-Tags (lazyOnload). Consent Mode gilt für alle — gemeinsamer dataLayer, ein consent update aktualisiert jedes gtag('config', 'AW-...').
Nach „Nur notwendige“:
conversion_event_submit_lead_formkann modelliert sein, nicht 1:1 gemessen- Smart Bidding bekommt Aggregat-Signale, mit Verzögerung und geringerer Granularität
- Tag Assistant zeigt Consent-Status pro Hit
Nach „Alle akzeptieren“ — volle _gcl_*-Cookies, vollere Attribution.
Wichtig: Ads-Conversion-Test in Incognito ohne Marketing-Einwilligung liefert anderes Ergebnis als nach Akzeptanz — kein Bug, sondern DSGVO.
DSGVO — Banner vs Consent Mode
| Anforderung (vereinfacht) | CookieBanner | Consent Mode |
|---|---|---|
| Information vor Cookies | Text + Policy-Link | Allein nicht genug |
| Granulare Wahl | „Anpassen“ mit Kategorien | Kategorien → gtag-Parameter |
| Marketing-Opt-in | „Nur notwendige“ als Option | default denied |
| Nachweis der Einwilligung | localStorage + optional Server-Log | Google-Logs (Ergänzung) |
localStorage ist kein Cookie — in Datenschutzerklärung dokumentieren. Für Audit optional Endpoint mit Entscheidungs-Hash + Timestamp (keine PII).
Banner-Kategorien:
- Notwendig — immer an (Session, CSRF; reCAPTCHA ggf. „notwendig“ — juristisch prüfen)
- Analyse →
analytics_storage - Marketing →
ad_storage,ad_user_data,ad_personalization
„Anpassen“ zeigt Kategorien, Toggle sind nicht interaktiv — nächster Schritt: echte Switches für partielle Einwilligung (Analyse ja, Marketing nein).
Consent Mode v2 testen
Tag Assistant Companion
- Produktionsseite in Incognito öffnen.
- Ohne Cookie-Akzeptanz Testformular senden.
- Tag Assistant Consent State —
deniedfür Ad/Analytics. - Alle akzeptieren — neu laden — Submit wiederholen.
- Vergleichen: GA4 Echtzeit, Ads-Conversions (24–48 h Verzögerung).
Chrome DevTools → Application
- Cookies — nach denied kein
_ga,_gcl_au(bis granted) - Local Storage —
cookieConsent,cookiePreferences
Google Ads — Diagnose
Unter Ziele → Einstellungen → Consent mode Status „Erkannt“ nach default + update. „Nicht erkannt“ = Tags ignorieren Signale oder default zu spät.
Checkliste vor DSGVO-Audit
-
consent defaultbeforeInteractive, vor GA4-Config -
consent updateauf jeden Banner-Button - Einwilligung aus localStorage nach Reload
- Formular + Chatbot in beiden Consent-Pfaden getestet
- Datenschutzerklärung beschreibt Kategorien und Google als Auftragsverarbeiter
- Keine Dark Patterns (vorgehakt Marketing)
Auswirkung auf Core Web Vitals
beforeInteractive Consent-Skript ist klein inline — minimaler LCP-Einfluss. GA4 afterInteractive + Ads lazyOnload bleibt gutes Layout nach Consent Mode — nicht alles auf beforeInteractive „für volle Daten“ verschieben.
Modellierte Conversions bei denied erfordern nicht volles Laden aller AW- vor Einwilligung — Google plant diesen Trade-off explizit.
GTM vs direktes gtag in layout.tsx
Viele Agenturen empfehlen Google Tag Manager als Consent-Hub. In Next.js 15 ist direktes gtag in layout.tsx gleichwertig — solange consent default vor allen gtag('config') steht. Vorteile gtag inline: weniger Third-Party-Container, vorhersehbares Verhalten mit Script strategy, keine GTM-Preview-Session auf Produktion. Vorteile GTM: Marketing ändert Tags ohne Deploy. DevStudio.it nutzt feste IDs in Code — Consent Mode ergänzt diese Architektur, ersetzt sie nicht.
Wichtig bei GTM: Consent Initialization-Tag muss feuern, bevor GA4/Ads-Tags aus dem Container laden. Bei inline-gtag reicht ein beforeInteractive-Block.
Konsistenz: Formular, Chatbot und Mehrsprachigkeit
Leads kommen aus Kontaktformular (page.tsx → /api/submissions) oder Chatbot (Chatbot.tsx → /api/chatbot/submit). Beide feuern nach HTTP 200 generate_lead und conversion_event_submit_lead_form. Consent-Tests müssen beide Pfade abdecken — sonst sieht Marketing Conversion-Lücken trotz korrektem Banner.
Locales /pl, /en, /de teilen layout.tsx und CookieBanner im locale layout. Bannertexte sind derzeit polnisch — nächster i18n-Schritt: übersetzte Buttons und Policy-Link /${locale}/polityka. Consent Mode ist sprachunabhängig.
Modellierte vs beobachtete Conversions — Erwartungen setzen
Bei default denied zeigt Google Ads modellierte Conversions neben beobachteten. Modellierung ist statistisch — nicht jede CRM-Anfrage erscheint 1:1 im Ads-Panel, wenn Nutzer Marketing abgelehnt haben. Das ist kein Implementierungsfehler, sondern DSGVO-konformes Design. Internes Reporting: CRM-Leads als Quelle der Wahrheit; Ads-Konversionen als Optimierungssignal mit Modellierungsanteil.
Marketing-Team briefen: Woche 1 nach Banner — Rückgang beobachteter Hits ist normal; Smart Bidding passt sich an, wenn Consent Mode korrekt erkannt wird.
Implementierungs-Zeitplan (1–2 Dev-Tage)
| Tag | Aufgabe | Prüfung |
|---|---|---|
| Tag 1 Vormittag | consent default beforeInteractive in layout |
Tag Assistant: denied vor Klick |
| Tag 1 Nachmittag | consent update in CookieBanner + localStorage-Restore |
Reload behält Wahl |
| Tag 2 Vormittag | Formular + Chatbot testen (denied / granted) | GA4 Echtzeit, kein _ga bei denied |
| Tag 2 Nachmittag | Ads-Diagnose + Datenschutzerklärung | Ads: Consent mode „Erkannt“ |
Nach Rollout 48 h warten, bevor Kampagnen beurteilt werden — Modellierung stabilisiert sich mit Traffic in beiden Consent-Zuständen.
FAQ
Brauche ich GTM statt gtag.js?
Nein. Consent Mode funktioniert mit direktem gtag in layout.tsx wie mit GTM. GTM erleichtert Tag-Verwaltung ohne Deploy — Next.js Script + feste IDs ist valides Muster.
Blockiert „Nur notwendige“ GA4 vollständig?
Mit Consent Mode sendet GA4 eingeschränkte Pings (Modellierung), aber ohne Analyse-Cookies. Berichte unvollständiger bis granted. Erwartetes Verhalten.
Braucht reCAPTCHA Marketing-Einwilligung?
Google reCAPTCHA ist eigener Dienst — oft „notwendig“ für Formularsicherheit, sendet aber Daten an Google. In Policy erwähnen. Consent Mode steuert reCAPTCHA-iFrame nicht — Skript ggf. erst bei Formular-Fokus laden.
Was wenn Nutzer localStorage löscht?
Banner erscheint wieder; default denied bis neue Entscheidung. Korrektes Verhalten.
Reicht Consent Mode v2 für Google Ads in Polen?
Technisch ja — mit default denied, update nach Einwilligung, DSGVO-konformem Banner. Rechtlich zusätzlich Datenschutzerklärung, ggf. AVV mit Google, Prozessdokumentation.
Warum drei AW-Tags?
Konten-/Kampagnen-Migration. Consent Mode aktualisiert gemeinsamen dataLayer — ein gtag('consent', 'update', …) reicht.
Zusammenfassung
Consent Mode v2 ist die Brücke zwischen DSGVO und effektiven Google Ads/GA4: default denied im EWR, Banner mit echter Wahl (wie CookieBanner.tsx), gtag consent update synchron mit localStorage, Tag-Assistant-Tests auf beiden Pfaden. Banner ohne Consent Mode ist halbe Implementierung; Tags ohne Banner ist Rechtsrisiko. Auf Next.js 15 default beforeInteractive, GA4 afterInteractive für Leads, Ads lazyOnload für Performance — dann Banner-Buttons an analytics_storage und ad_-v2-Parameter anbinden.
Consent Mode bei Ihnen umsetzen?
- Kontakt — Banner, GA4 und Google Ads DSGVO-konform verbinden
- Datenschutz und Cookies — Dokumentationsmuster auf der Seite
- Websites — Next.js, Analyse und Rechtskonformität in einem Projekt