Einleitung
In der heutigen Webentwicklung ist es entscheidend, den Bedarf an Auswertungen mit dem Schutz der Privatsphäre in Einklang zu bringen. Dieser Leitfaden führt durch die Implementierung einer datenschutzkonformen Google-Analytics-Einrichtung über den Google Tag Manager in einer Next.js-Anwendung – einschließlich einer Einwilligungsverwaltung.
Was bedeutet DSGVO-Konformität?
Die Datenschutz-Grundverordnung verlangt unter anderem:
- vor der Erhebung von Nutzerdaten die ausdrückliche Zustimmung einzuholen
- Nutzern die Möglichkeit zu geben, nicht notwendiges Tracking abzulehnen
- klar über die Datenerfassung zu informieren
- Nutzern zu ermöglichen, ihre Auswahl jederzeit zu ändern
Was ist der Google Tag Manager?
Der Google Tag Manager ist ein System zur Verwaltung von Tracking-Skripten. Damit können Sie:
- verschiedene Tracking-Skripte einbinden
- mehrere Analysewerkzeuge verwalten
- steuern, wann und abhängig von der Einwilligung welche Skripte ausgelöst werden
- Tracking-Einstellungen anpassen, ohne den Anwendungscode jedes Mal zu ändern
Was ist Google Analytics 4?
Google Analytics 4 bietet erweiterte Datenschutzfunktionen, unterstützt den Einwilligungsmodus, erlaubt flexible Formen der Datenerfassung und arbeitet mit dem Google Tag Manager zusammen.
Implementierungsanleitung
Abhängigkeit einrichten
yarn add vanilla-cookieconsent
Tag Manager zunächst mit verweigerter Einwilligung laden
Im Standardzustand werden alle nicht notwendigen Speicherarten verweigert. Ersetzen Sie YOUR_GTM_ID durch die eigene Kennung.
// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html lang="de">
<head>
<Script id="gtm-script" strategy="afterInteractive">
{`
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('consent', 'default', {
ad_storage: 'denied',
analytics_storage: 'denied',
personalization_storage: 'denied',
functionality_storage: 'denied',
ad_user_data: 'denied',
ad_personalization: 'denied'
});
(function(w,d,s,l,i){
w[l]=w[l]||[];
w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});
var f=d.getElementsByTagName(s)[0], j=d.createElement(s),
dl=l!='dataLayer'?'&l='+l:'';
j.async=true;
j.src='https://www.googletagmanager.com/gtm.js?id='+i+dl;
f.parentNode.insertBefore(j,f);
})(window,document,'script','dataLayer','YOUR_GTM_ID');
`}
</Script>
</head>
<body>{children}</body>
</html>
);
}
Banner für die Cookie-Einwilligung implementieren
Die Einwilligungsverwaltung sollte auf die Datenschutzerklärung verweisen, eine Auswahl zwischen allen und nur notwendigen Diensten ermöglichen und den Einwilligungszustand des Tag Managers aktualisieren.
// components/CookieConsent.tsx
'use client';
import { createContext, useContext, useEffect, useState } from 'react';
import 'vanilla-cookieconsent/dist/cookieconsent.css';
import * as CookieConsent from 'vanilla-cookieconsent';
const CookieConsentContext = createContext<string[]>([]);
export const useCookieConsent = () => useContext(CookieConsentContext);
export function CookieConsentProvider({ children }) {
const [acceptedServices, setAcceptedServices] = useState<string[]>([]);
useEffect(() => {
const updateGtmConsent = () => {
if (typeof window.gtag !== 'function') return;
const preferences = CookieConsent.getUserPreferences();
const categories = preferences.acceptedCategories || [];
const services = preferences.acceptedServices || {};
const googleAccepted =
categories.includes('analytics') &&
services.analytics?.includes('google');
window.gtag('consent', 'update', {
analytics_storage: googleAccepted ? 'granted' : 'denied',
ad_storage: googleAccepted ? 'granted' : 'denied',
personalization_storage: googleAccepted ? 'granted' : 'denied',
functionality_storage: 'granted',
ad_user_data: googleAccepted ? 'granted' : 'denied',
ad_personalization: googleAccepted ? 'granted' : 'denied'
});
};
const updateAcceptedServices = () => {
const services = CookieConsent.getUserPreferences().acceptedServices || {};
setAcceptedServices(Object.values(services).flat());
};
const updateConsent = () => {
updateAcceptedServices();
updateGtmConsent();
};
CookieConsent.run({
cookie: {
domain: process.env.NEXT_PUBLIC_COOKIE_DOMAIN || 'ihre-domain.de'
},
categories: {
necessary: { enabled: true, readOnly: true },
analytics: {
services: { google: { label: 'Google Analytics' } }
}
},
language: {
default: 'de',
translations: {
de: {
consentModal: {
title: 'Datenschutzeinstellungen',
description: 'Wir verwenden Cookies. Bitte wählen Sie Ihre Einstellungen.',
acceptAllBtn: 'Alle akzeptieren',
acceptNecessaryBtn: 'Nur notwendige akzeptieren',
showPreferencesBtn: 'Einstellungen verwalten'
},
preferencesModal: {
title: 'Cookie-Einstellungen',
sections: [
{
title: 'Notwendig',
description: 'Für die Funktion der Website erforderlich.',
linkedCategory: 'necessary'
},
{
title: 'Analyse',
description: 'Hilft uns, die Nutzung der Website zu verstehen.',
linkedCategory: 'analytics'
}
],
acceptAllBtn: 'Alle akzeptieren',
acceptNecessaryBtn: 'Nur notwendige akzeptieren',
savePreferencesBtn: 'Auswahl speichern'
}
}
}
},
onChange: updateConsent,
onFirstConsent: updateConsent
});
if (CookieConsent.getUserPreferences()?.acceptedCategories) {
updateConsent();
}
}, []);
return (
<CookieConsentContext.Provider value={acceptedServices}>
{children}
</CookieConsentContext.Provider>
);
}
Legen Sie die eigene Domain fest oder verwenden Sie dafür wie im Beispiel eine Umgebungsvariable.
Den Anbieter einbinden
// app/providers.tsx
'use client';
import { CookieConsentProvider } from '@/components/CookieConsent';
export default function Providers({ children }) {
return <CookieConsentProvider>{children}</CookieConsentProvider>;
}
Der Anbieter wird anschließend im Layout um den eigentlichen Seiteninhalt gelegt:
// app/layout.tsx
import Providers from '@/app/providers';
export default function RootLayout({ children }) {
return (
<html lang="de">
<body>
<Providers>{children}</Providers>
</body>
</html>
);
}
Weitere Tracking-Dienste ergänzen
- Fügen Sie einen neuen Dienst in der passenden Kategorie von
CookieConsent.run()hinzu. - Erstellen Sie eine Funktion, die den Einwilligungszustand des neuen Dienstes aktualisiert.
- Rufen Sie diese Funktion bei der ersten Einwilligung und bei Änderungen auf.
- Ergänzen Sie die Texte des Einstellungsfensters um den neuen Dienst.
Datenschutzseite zur Next.js-Anwendung hinzufügen
Nutzer sollten ihre Auswahl später wieder öffnen und ändern können. Dafür reicht eine Schaltfläche auf der Datenschutzseite:
// app/datenschutz/page.tsx
'use client';
import * as CookieConsent from 'vanilla-cookieconsent';
export default function Datenschutz() {
return (
<main>
<h1>Datenschutzeinstellungen</h1>
<p>Hier können Sie Ihre Cookie-Auswahl jederzeit ändern.</p>
<button onClick={() => CookieConsent.showPreferences()}>
Cookie-Einstellungen öffnen
</button>
</main>
);
}
Zusammenfassung
Die Umsetzung berücksichtigt die Datenschutzrechte der Nutzer, die technische Einbindung, die Verwaltung von Einwilligungen und einen nachvollziehbaren Umgang mit Daten.
Wenn Sie diesen Leitfaden befolgen, entsteht eine solide Analyseeinrichtung, die die Privatsphäre der Nutzer respektiert und gleichzeitig Einblicke in die Nutzung der Anwendung ermöglicht.
Weiterführende Links
Gruß
Julian