Consent-Banner

Beaconry bringt seinen eigenen Zwei-Button-Consent-Banner mit, damit du kein separates Cookie-Plugin brauchst, um konform zu sein. Er folgt dem strengen EU-Modell: nichts wird getrackt, bis der Besucher aktiv akzeptiert. Keine vorausgewählten Boxen, kein "durch Weitersurfen stimmst du zu", keine Events auf der Leitung vor einem Klick. Der Banner ist das nl-data-gate-Modul, dieselbe Engine, aus der die restliche Pipeline ihren Consent-Status liest.

Lesezeit: ~6 MinZuletzt aktualisiert: 2026-06-08

Warum ein eingebauter Banner

Server-seitiges Tracking befreit dich nicht von der Einwilligung. Egal ob die Anfrage Browser-zu-Meta oder Server-zu-Meta läuft, du verarbeitest weiterhin die Daten eines Besuchers zu Werbezwecken, und in der EU braucht das eine Rechtsgrundlage. Beaconrys gesamte Pipeline hängt an einem einzigen Signal, dem nl_pref-Cookie, und der Banner ist, was es schreibt. Du kannst stattdessen deinen eigenen Consent-Manager mitbringen (siehe "Den Banner ausschalten" weiter unten), aber wenn du keinen hast, macht der mitgelieferte Banner Beaconry out of the box konform, ohne ein einziges zusätzliches Plugin.

Eines sei klargestellt: das Gate ist echt. Es stoppt die komplette Pipeline, server-seitiger Dispatch inklusive, nicht nur Browser-Pixel. Bis nl_pref ein analytics: true trägt, feuert die Browser-Engine gar nichts und der REST-Endpoint weist ab, was an Wenigem doch durchkommen könnte. Kein Akzeptieren heißt kein Tracking, Punkt.

Zwei Buttons, keine implizite Einwilligung

Der Banner rendert exakt zwei Aktionen plus einen Datenschutz-Link:

  • Akzeptieren schreibt Consent mit Analytics und Marketing auf true und lässt die Pipeline laufen.
  • Ablehnen schreibt Consent mit Analytics und Marketing auf false. Die Entscheidung wird gespeichert, sodass der Besucher nicht auf jeder Seite genervt wird, aber nichts wird getrackt.
  • Datenschutz-Link zeigt auf deine Datenschutzerklärung (konfigurierbar, siehe unten).

Es gibt bewusst keinen Pfad für implizite Einwilligung. Scrollen akzeptiert nicht. Auf die nächste Seite navigieren akzeptiert nicht. Den Banner mit Escape schließen zählt als Ablehnen, nicht als Akzeptieren, denn das Wegklicken eines Dialogs darf niemals als Zustimmung gelesen werden. Der einzige Weg, Tracking zu starten, ist ein expliziter Klick auf Akzeptieren. Das ist das Verhalten, das die EU-Regel "keine implizite Einwilligung" verlangt, und es ist der Default ohne jede Konfiguration.

Bis eine Entscheidung vorliegt, bleibt der Banner einfach oben und es wird kein Consent-Cookie geschrieben. Auf der ersten Seite, auf der der Besucher Akzeptieren klickt, wird das Cookie gesetzt und ein nl:gate:changed-Event feuert, damit die Tracking-Engine sofort auf eben dieser Seite starten kann, ohne Reload.

Das nl_pref-Cookie

Die einzige Wahrheitsquelle für Consent ist ein First-Party-Cookie namens nl_pref, client-seitig mit path=/; SameSite=Lax und (auf HTTPS) dem Secure-Flag geschrieben. Es enthält ein JSON-Objekt, kein nacktes Flag:

{"analytics":true,"marketing":true,"functional":true,"timestamp":1733650800,"version":1}

Was jedes Feld bedeutet:

  • analytics ist das Gate, das Beaconry tatsächlich liest. true lässt Events fließen, false blockt sie.
  • marketing hält dieselbe Akzeptieren/Ablehnen-Entscheidung fest (der Banner ist binär, also bewegen sich beide gemeinsam) und wird beim Widerruf genutzt, um zu wissen, welche Tracker-Cookies zu löschen sind.
  • functional ist immer true; unbedingt erforderliche Cookies brauchen kein Opt-in.
  • timestamp ist die Unix-Sekunde, in der die Entscheidung getroffen wurde, nützlich für Einwilligungs-Nachweise.
  • version lässt das Schema sich weiterentwickeln, ohne alte Cookies falsch zu lesen.

Das Cookie hält ein Jahr (max-age 365 Tage), dann erscheint der Banner wieder, sodass Consent periodisch erneuert statt für immer angenommen wird. Der Wert wird defensiv zurückgelesen: alles, was kein gültiges JSON mit einem booleschen analytics-Key ist, wird als "noch keine Entscheidung" behandelt und der Banner erscheint erneut, sodass ein korruptes oder von Hand editiertes Cookie niemals still Tracking aktivieren kann.

Der Widerruf der Einwilligung räumt aktiv auf. Gemäß DSGVO Artikel 7(3) muss der Widerruf so einfach sein wie die Erteilung. Wenn ein Besucher von Akzeptieren zu Ablehnen wechselt, schreibt die Engine nicht nur nl_pref neu, sie lässt auch die gängigen First-Party-Tracker-Cookies auslaufen, die während der eingewilligten Sitzung gesetzt wurden (Google Analytics _ga* / _gcl_*, die engine-eigenen nl_sid / nl_dev / nl_ref / nl_ext, LinkedIn li_fat_id, Meta _fbp / _fbc, TikTok _ttp / ttclid und Konsorten) und ruft, falls ein Meta Pixel vorhanden ist, fbq('consent', 'revoke') auf, damit es sofort aufhört zu senden. Der Besucher bekommt beim Widerruf ein sauberes Cookie-Glas, nicht nur einen umgelegten Schalter.

Anpassung im Banner-Tab

Alles, was der Besucher sieht, lebt unter wp-admin, Beaconry, Cookie Banner. Nichts davon ist Pflicht, jedes Feld fällt auf einen sinnvollen mitgelieferten Default zurück, sodass eine frische Installation bereits einen funktionierenden, lokalisierten Banner hat.

Aktivieren / deaktivieren

Ein einziger Master-Schalter, "Consent-Banner beim ersten Besuch anzeigen". Das Status-Badge daneben zeigt Sichtbar oder Versteckt, sodass du den aktuellen Zustand auf einen Blick siehst.

Texte

Vier Textfelder, jedes optional, jedes fällt auf den lokalisierten Default zurück, wenn es leer bleibt:

FeldWas es setztDefault (EN)
NachrichtDer Fließtext des BannersWe use cookies for anonymous reach measurement. You can revoke at any time.
Akzeptieren-ButtonBeschriftung der Akzeptieren-AktionAccept
Ablehnen-ButtonBeschriftung der Ablehnen-AktionReject
Datenschutz-Link-TextBeschriftung des Datenschutz-LinksPrivacy

Die mitgelieferten Defaults sind pro Sprache hartcodiert (Deutsch und Englisch sind in der Engine enthalten), weil der Banner sehr früh im Seiten-Lebenszyklus feuert, bevor der volle WordPress-Übersetzungs-Stack bereit ist, sodass er sich für seinen ersten Paint nicht auf ein spät geladenes Sprach-Override verlassen kann.

Farben

Drei optionale Farbfelder, "Hintergrund", "Textfarbe" und "Akzent (Buttons)". Lass eines davon leer und der Banner erbt diesen Token aus deinem aktiven Theme, Beaconry überschreibt eine Banner-Farbe nur, wenn du explizit einen Wert setzt. Jedes Feld hat einen nativen Color-Picker neben einem Hex-Input, sodass du #ff6a1a tippen oder es visuell auswählen kannst. Die Akzentfarbe färbt den Akzeptieren-Button; die Ablehnen-Aktion bleibt bewusst ein dezenter unterstrichener Text-Button, damit die primäre Wahl visuell offensichtlich ist, ohne Dark Patterns.

Datenschutz-URL

Wohin der Datenschutz-Link zeigt. Lass es leer und Beaconry verlinkt auf /datenschutz/ der aktuellen Site. Setze es auf eine beliebige URL, um anderswohin zu zeigen. Auf mehrsprachigen Installationen wird diese eine URL zur Request-Zeit auf die richtige sprachspezifische Seite aufgelöst, behandelt im nächsten Abschnitt.

Den Banner später erneut öffnen

Consent muss widerrufbar sein. Platziere den [beaconry_revoke_consent]-Shortcode auf deiner Datenschutzseite (oder irgendwo) und er rendert einen Inline-Link "Cookies verwalten", der nl_pref löscht und den Banner erneut zeigt, sodass der Besucher es sich anders überlegen kann. Überschreibe die Beschriftung mit [beaconry_revoke_consent text="Cookies verwalten"]. Unter der Haube trägt der Link das data-nl-cookie-settings-Attribut, auf das die Banner-Engine lauscht, sodass er den Live-Dialog neu öffnet statt nur neu zu laden.

Barrierefreiheit

Der Banner ist ein echter Modal-Dialog, kein gestyltes div, und er verhält sich auch so für Tastatur- und Screenreader-Nutzer:

  • role="dialog" + aria-modal="true" mit einem lokalisierten aria-label ("Cookie settings" / "Cookie-Einstellungen"), sodass assistive Technik ihn als Modal-Dialog mit Namen ansagt.
  • Der Fokus wandert beim Anzeigen in den Dialog. Wenn der Banner hereingleitet, landet der Fokus auf dem Akzeptieren-Button, sodass ein Tastatur- oder Screenreader-Nutzer sofort im Dialog ist, statt ihn zu suchen.
  • Der Fokus ist gefangen. Tab und Shift+Tab zirkulieren nur zwischen dem Datenschutz-Link und den beiden Buttons; du kannst nicht per Tab in die Seite hinter dem Dialog hinausspringen, solange eine Entscheidung aussteht.
  • Escape schließt als Ablehnen. Gemäß WCAG 2.1 muss ein Dialog auf Escape reagieren; hier speichert Escape eine Ablehnen-Entscheidung (niemals ein stilles Akzeptieren) und schließt den Banner.
  • Sichtbare Fokus-Indikatoren. Buttons und der Datenschutz-Link haben explizite :focus-visible-Outlines, sodass der Tastatur-Fokus unabhängig vom Theme immer sichtbar ist.
  • Nach einer Entscheidung wird der Fokus freigegeben. Das aktive Element wird bei Akzeptieren oder Ablehnen geblurrt, sodass der Fokus sauber in den Dokumentfluss zurückkehrt.

Er respektiert außerdem prefers-reduced-motion: die Hereingleit-Transition wird durch ein schlichtes Opacity-Fade ersetzt für Besucher, die das OS um reduzierte Bewegung gebeten haben. Und er wird abseits des kritischen Pfades gerendert (in einem Idle-Callback), sodass er niemals den First Paint blockiert oder deinen Largest Contentful Paint verschlechtert.

Mehrsprachigkeit (WPML und Polylang)

Zwei Dinge müssen auf einer mehrsprachigen Site lokalisiert werden: der Banner-Text und die Datenschutz-URL (ein deutscher Besucher sollte auf /datenschutz/ landen, ein englischer auf /privacy-policy/). Beaconry handhabt beides, und der richtige Ort zum Übersetzen hängt davon ab, welches Plugin du fährst. Der Banner-Tab zeigt einen Hinweis "WPML detected" oder "Polylang detected", der dich auf den exakten Screen verweist.

Banner-Text

Die vier Textfelder (Nachricht, Akzeptieren, Ablehnen, Datenschutz-Link-Text) plus die Datenschutz-URL werden als übersetzbare Strings deklariert:

  • WPML. Beaconry liefert eine wpml-config.xml, die die Banner-Options-Keys als Admin-Texte deklariert, sodass sie automatisch in WPML, String Translation unter der Domain admin_texts_bcnr_settings erscheinen. Übersetze dort jedes Feld pro aktiver Sprache; WPML gibt den übersetzten Wert zurück, wenn die Settings auf einem Request in einer Nicht-Standard-Sprache gelesen werden, sodass Beaconrys normaler Lesepfad die Übersetzung transparent aufnimmt, ohne zusätzliche Verkabelung.
  • Polylang. Polylang hat keine deklarative Config-Datei, also registriert Beaconry dieselben Keys via pll_register_string zur Admin-Zeit. Sie tauchen unter Sprachen, Übersetzungen in der String-Gruppe Beaconry auf. Es werden nur Felder registriert, die du tatsächlich ausgefüllt hast (ein leeres Feld bleibt auf seinem mitgelieferten lokalisierten Default und müllt die Liste nicht zu).

Wenn du die Textfelder komplett leer lässt, bekommst du trotzdem korrekte sprachspezifische Texte aus den mitgelieferten deutschen und englischen Defaults, kein Übersetzungsschritt für diese beiden nötig. Der String-Translation-Weg ist für den Fall, dass du deine eigene Formulierung pro Sprache willst.

Sprachspezifische Datenschutz-URL

Du gibst eine Datenschutz-URL im Banner-Tab ein, und Beaconry löst sie zur Request-Zeit auf die Sprache des Besuchers auf. Der Resolver läuft durch den bcnr_privacy_url-Filter:

  1. Wenn kein mehrsprachiges Plugin aktiv ist, geht die URL unverändert durch.
  2. Die konfigurierte URL wird via url_to_postid() auf einen WordPress-Post gemappt. Löst sie nicht auf einen Post auf (ein statischer Pfad, eine externe URL), wird sie unverändert zurückgegeben, kein Raten.
  3. Andernfalls fragt Beaconry WPML (wpml_object_id) oder Polylang (pll_get_post) nach der Übersetzung dieser Seite in der aktuellen Sprache und gibt den übersetzten Permalink zurück.
  4. Gibt es keine Übersetzung für die aktuelle Sprache, fällt es auf die Original-URL zurück. Der Resolver gibt niemals leer zurück.

Du zeigst den Banner also etwa einmal auf deine englische Datenschutzerklärung, legst ihre deutsche Übersetzung als normale WPML/Polylang-Seitenübersetzung an, und deutsche Besucher bekommen automatisch den deutschen Permalink im Banner-Link. Kein zweites URL-Feld, keine sprachspezifische Override-Liste.

Für exotische Setups (TranslatePress, MultilingualPress, ein Custom-Build) ist die Erkennung via bcnr_is_multilingual filterbar, und du kannst bcnr_privacy_url direkt hooken, um deinen eigenen Resolver bereitzustellen.

Den Banner ausschalten (bring deinen eigenen Consent mit)

Wenn du bereits eine dedizierte Consent-Management-Plattform fährst, schalte Beaconrys Banner aus und lass deine CMP den Consent steuern. Der Vertrag ist simpel: deine CMP muss das nl_pref-Cookie selbst schreiben. Konkret:

  • Der Cookie-Name muss exakt nl_pref sein.
  • Der Wert muss ein JSON-Objekt sein, das "analytics" mit einem Boolean enthält (zum Beispiel {"analytics": true, "marketing": true}).
  • Es muss gesetzt sein, bevor irgendein Seitenaufruf passiert, den du tracken willst.

Mit ausgeschaltetem Banner und ohne vorhandenes Cookie feuert nichts, das ist der sichere Default, kein Bug. Schalte den Banner nur aus, wenn du eine externe Lösung hast, die das Cookie schreibt, oder wenn deine Site echt in einer Region ohne Einwilligungspflicht operiert. Es gibt auch eine Power-User-Nuance für Nicht-EU-Sites: mit deaktiviertem Banner und ohne vorhandenes Cookie schreibt der Loader ein permissives nl_pref, sodass Tracking ohne Banner laufen kann. Nutze das nur dort, wo du sicher bist, dass Consent rechtlich nicht erforderlich ist.

Nutzt die Marketing-Site das hier?

Nein, und das ist bewusst. beaconry.app liefert kein GA4, kein Meta Pixel, keine Tracking-Engine und keinen Cookie-Banner aus, weil es nichts gibt, worin man einwilligen könnte. Ein Produkt, das datenschutzfreundliches Tracking verkauft, sollte nicht still die Leute tracken, die darüber lesen. Der hier beschriebene Banner ist, was deine Besucher auf deiner Site sehen, sobald du das Plugin installierst und einschaltest.