JavaScript SDK (Client) Integration
Das HashEntry CMP SDK ist ein Skript ohne Abhängigkeiten, das das Cookie-Banner anzeigt, die von Ihnen markierten Skripte blockiert, bis der Besucher sie erlaubt, und jede Entscheidung auf dem HashEntry-Server erfasst. Es kann außerdem Zustimmungen zu Dokumenten (AGB, Verträge, Richtlinien) erfassen — siehe Dokumentzustimmung & Signatur.
Diese Seite beschreibt, was das SDK heute tut. Wo ein Verhalten von einer Dashboard-Einstellung oder von Ihrem eigenen Markup abhängt, wird darauf hingewiesen.
Schnellstart
Abschnitt betitelt „Schnellstart“<head> <script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" async ></script></head>Das SDK lädt die an Ihren API-Schlüssel gebundene Konfiguration (Banner-Design, Texte, Kategorien, Dokumente, Verhaltenseinstellungen) vom Server und entscheidet, ob für diesen Besucher ein Banner erforderlich ist.
Zwei Voraussetzungen müssen erfüllt sein, bevor eine Cookie-Entscheidung auf dem Server erfasst werden kann:
- Die Website ist im Dashboard verifiziert. Anfragen für eine nicht verifizierte Website werden mit
403 SITE_NOT_VERIFIEDabgelehnt. - Der Website ist ein Cookie-Richtlinien-Dokument zugeordnet. Siehe den nächsten Abschnitt.
Ein Cookie-Richtlinien-Dokument ist erforderlich
Abschnitt betitelt „Ein Cookie-Richtlinien-Dokument ist erforderlich“Eine Cookie-Einwilligung wird nur erfasst, wenn sie auf genau die aktive Version eines Dokuments vom Typ cookie_policy verweist, das der Website zugeordnet ist. Die akzeptierte Version der Richtlinie ist Teil des Nachweises, daher lockert das SDK diese Regel nicht.
- Ist keine veröffentlichte Cookie-Richtlinie zugeordnet, zeigt das SDK das Banner nicht an (auch nicht das Widget oder den Link „Do Not Sell“) und hält in jeder Region alle markierten, nicht notwendigen Skripte blockiert: Eine Wahl, die nicht als Nachweis gespeichert werden kann, wird nicht erhoben. Die Ereignisse
consent:errorunderrorwerden mitcode: "COOKIE_POLICY_MISSING"ausgelöst, und der Fehler wird in die Browserkonsole geschrieben.CMP.accept()/CMP.reject()liefernsuccess: false,error.code = "COOKIE_POLICY_MISSING"undpending_sync: false; nichts wird gespeichert, angewendet oder in die Warteschlange gestellt. Sobald eine Richtlinie zugeordnet ist, erscheint das Banner beim nächsten Seitenaufruf, und der Besucher entscheidet anhand dieser Version. Eine Einwilligung, die aufgezeichnet wurde, während eine Richtlinie zugeordnet war, bleibt gültig. - Eine Entscheidung wird nie zurückgehalten und später mit einer Richtlinienversion gesendet, die der Besucher nicht gesehen hat. Hat eine frühere SDK-Version eine solche Entscheidung in der lokalen Warteschlange hinterlassen, wird sie verworfen (
consent:errormitfinal: true,reprompt: true) und der Besucher wird erneut gefragt. - Die einzige Ausnahme ist der Modus
localohnedata-site: Es wird nichts an den Server gesendet, daher wird das Banner angezeigt und die Entscheidungen bleiben im Browser (local_only: true). - Verweist die Einwilligung auf eine Version, die nicht die aktive ist, antwortet der Server mit
409 CONFIG_OUTDATED. Siehe Erneute Einwilligung und geänderte Dokumentversionen.
Was Sie tun müssen: Erstellen Sie im Dashboard ein Cookie-Richtlinien-Dokument, veröffentlichen Sie eine Version in jeder Sprache, die Ihr Banner verwendet, und ordnen Sie es der Website zu.
Skripte vor der Einwilligung blockieren
Abschnitt betitelt „Skripte vor der Einwilligung blockieren“Nur Skripte, die Sie markieren, werden blockiert. Das SDK durchsucht die Seite nicht nach Trackern und fängt keine Skripte ab, die Sie unverändert lassen: Ein normales <script>-Tag wird sofort ausgeführt, mit oder ohne Einwilligung.
Um ein Skript zurückzuhalten, ändern Sie dessen type in text/plain und geben Sie seine Kategorie an:
<!-- Inline-Skript: wird erst ausgeführt, nachdem "analytics" erlaubt wurde --><script type="text/plain" data-cookie-category="analytics"> /* Analytics-Snippet */</script>
<!-- Externes Skript: data-src statt src verwenden --><script type="text/plain" data-cookie-category="marketing" data-src="https://connect.facebook.net/en_US/fbevents.js"></script>- Die Kategorienamen müssen mit den Kategorieschlüsseln Ihres Banners übereinstimmen (
analytics,marketing,preferencesoder Ihre eigenen Schlüssel). Mitnecessarymarkierte Skripte werden sofort aktiviert, noch bevor die Konfiguration geladen ist. - Markierte Skripte, die der Seite später hinzugefügt werden (SPA-Navigation, Tag-Injektion), werden ebenfalls behandelt.
- Ein Skript, das bereits ausgeführt wurde, kann nicht gestoppt werden. Widerruft ein Besucher eine Kategorie, deren Skripte auf der aktuellen Seite ausgeführt wurden, löscht das SDK die bekannten Cookies dieser Kategorie und lädt die Seite standardmäßig neu (siehe
reload_on_revoke). - Wird eine Kategorie widerrufen, löscht das SDK die Cookies / Speichereinträge, die in Ihrer Banner-Konfiguration für diese Kategorie aufgeführt sind, sowie eine kleine eingebaute Liste bekannter Namen. Cookies, die es nicht kennt, werden nicht gelöscht, und Drittanbieter-Cookies auf anderen Domains können von Ihrer Seite aus nicht gelöscht werden.
Attribute des Script-Tags
Abschnitt betitelt „Attribute des Script-Tags“| Attribut | Standard | Beschreibung |
|---|---|---|
data-site | — | API-Schlüssel der Website. Im Modus remote erforderlich; auch in den anderen Modi nötig, damit Entscheidungen auf dem Server erfasst werden. |
data-mode | local-fallback | Konfigurationsquelle: remote, local, local-fallback. Siehe Betriebsmodi. |
data-language | auto | Banner-Sprache. auto verwendet <html lang>, danach die Browser-Sprache. |
data-region | auto | Erzwingt eine Region oder ein Regelwerk (DE, US, gdpr, ccpa, none, …) anstelle der Erkennung. Dies ist die Compliance-Region (welchen Regeln das Banner folgt); sie legt weder den Speicherort der Daten noch den aufgerufenen API-Host fest. |
data-config | — | Inline-JSON-Konfiguration (für local / local-fallback). |
data-debug | false | true gibt Debug-Logs aus. Fehler und Warnungen werden immer in der Konsole ausgegeben. |
data-headless | false | true rendert überhaupt keine UI (Banner, Widget, „Do Not Sell“-Link). Siehe Headless-Modus. |
data-consent-mode | Dashboard-Einstellung | true / false schaltet Google Consent Mode v2 zwingend ein oder aus. Siehe Google Consent Mode v2. |
data-reload-on-revoke | Dashboard-Einstellung | true / false überschreibt das Verhaltens-Flag reload_on_revoke. |
data-modules | — | Module, die vorab geladen werden sollen, z. B. documents, preferences. Siehe Bundles und bei Bedarf geladene Module. |
data-module-base | Ordner des Skripts selbst | Basis-URL, von der die Moduldateien geladen werden. Nur nötig, wenn sie nicht neben cmp.js ausgeliefert werden. |
data-api-url | HashEntry-API | API-Basis-URL für einen First-Party-Proxy oder eine eigene Domain. Hat die Datenregion Ihres Kontos einen eigenen API-Host, teilt die Konfigurationsantwort ihn mit (api_base_url) und das SDK verwendet ihn für alle weiteren Aufrufe; der im Panel erzeugte Einbettungscode enthält dann bereits das passende data-api-url. Ein hier von Ihnen gesetzter Wert hat immer Vorrang. |
JavaScript API (window.CMP)
Abschnitt betitelt „JavaScript API (window.CMP)“window.CMP existiert, sobald das Skript ausgeführt wurde. Methoden, die etwas erfassen, geben ein Promise mit einem Ergebnisobjekt zurück; sie werfen keine Ausnahmen.
CMP.ready(() => { /* Konfiguration geladen, Einwilligungsstatus ausgewertet */ });
// BannerCMP.show(); // Banner öffnen (z. B. über einen Footer-Link)CMP.hide();
// Entscheidungen — jede gibt Promise<ConsentResult> zurückCMP.accept(); // alle Kategorien erlaubenCMP.accept({ marketing: false }); // alle außer marketing erlaubenCMP.reject(); // nur notwendigeCMP.withdraw(); // die gespeicherte Einwilligung widerrufen
// StatusCMP.getConsent(); // ConsentState oder nullCMP.hasConsent('analytics'); // boolean ("necessary" ist immer true)
// SpracheCMP.setLanguage('de');CMP.getLanguage();CMP.setLocale('de', { ccpa: { optOut: 'Widersprechen' } }); // Texte für eine Sprache
// Metadaten: werden jeder danach erfassten Einwilligung und Zustimmung hinzugefügtCMP.setMetadata({ order_id: 'ORD-54321' });CMP.setMetadata('customer_id', 'CUST-999');CMP.getMetadata();
// Regions-Override, Theme, API-URL, lokale KonfigurationCMP.setRegion('DE');CMP.setTheme({ primaryColor: '#0F766E' });CMP.setApiUrl('/hashentry-api');CMP.getApiUrl();CMP.setConfig({ banner_config: { /* … */ } });
// EreignisseCMP.on('consent:given', (payload) => {});CMP.off('consent:given', handler);
// Dokumente (bei Bedarf geladen — siehe "Dokumentzustimmung & Signatur")CMP.showDocumentApproval('terms-of-service', { language: 'en' });CMP.approveDocument('terms-of-service', { /* … */ });CMP.withdraw()
Abschnitt betitelt „CMP.withdraw()“Der Widerruf schaltet alle nicht notwendigen Kategorien aus, löscht die bekannten Cookies dieser Kategorien, setzt Google Consent Mode auf denied, sendet eine Entscheidung withdrawn an den Server (sofern eine Einwilligung gespeichert war), entfernt die gespeicherte Einwilligung aus dem Browser und zeigt — in Opt-in-Regionen — das Banner erneut an. Wurden Skripte einer widerrufenen Kategorie auf der Seite bereits ausgeführt, wird die Seite neu geladen, sofern reload_on_revoke nicht ausgeschaltet ist.
CMP.setLanguage(lang)
Abschnitt betitelt „CMP.setLanguage(lang)“Ändert die Sprache des geöffneten Banners und lädt die Konfiguration für diese Sprache neu, weil Dokumentversionen sprachspezifisch sind: Spätere Einwilligungen verweisen dann auf die Version der Cookie-Richtlinie in der neuen Sprache. Hat das Banner keine Übersetzung für die Sprache, fällt es auf die Standardsprache des Banners zurück.
CMP.setMetadata(...)
Abschnitt betitelt „CMP.setMetadata(...)“Die Werte werden zusammengeführt und als metadata mit jeder späteren Cookie-Entscheidung und Dokumentzustimmung gesendet. Der Server akzeptiert höchstens 30 Schlüssel und etwa 16 KB Metadaten pro Datensatz.
Die API aufrufen, bevor das Skript geladen ist
Abschnitt betitelt „Die API aufrufen, bevor das Skript geladen ist“<script> window.__CMP_QUEUE = window.__CMP_QUEUE || []; window.__CMP_QUEUE.push(['setLanguage', 'de']); window.__CMP_QUEUE.push(['setMetadata', { order_id: 'ORD-12345' }]); window.__CMP_QUEUE.push(['on', 'consent:given', (p) => console.log(p)]);</script>In die Warteschlange gestellte Aufrufe werden der Reihe nach ausgeführt, wenn das SDK startet. Eine auf diese Weise gesetzte Sprache wird von der automatischen Erkennung nicht überschrieben.
Ergebnisobjekte
Abschnitt betitelt „Ergebnisobjekte“ConsentResult (accept, reject, withdraw)
Abschnitt betitelt „ConsentResult (accept, reject, withdraw)“{ success: true, consent_token: 'ct_…', proof_hash: '…', // 64 Hex-Zeichen created_at: '2026-10-10T10:00:00+00:00', idempotency_key: '…' // eine UUID pro Benutzeraktion, bei jedem Wiederholungsversuch wiederverwendet}success ist nur dann true, wenn der Server den Datensatz angenommen hat. Andernfalls:
{ success: false, consent_token: '', proof_hash: '', created_at: '…', error: { code: 'NETWORK_ERROR', status: 0, message: '…' }, pending_sync: true, // bleibt in der lokalen Warteschlange, wird erneut versucht idempotency_key: '…'}error.codeist der Maschinencode des Servers oder einer der unten aufgeführten SDK-Codes;error.statusist der HTTP-Status (0, wenn keine Antwort empfangen wurde).pending_sync: truebedeutet, dass die Entscheidung im Browser angewendet ist und in einer lokalen Warteschlange (localStorage) wartet. Sie wird beim nächsten Seitenaufruf, wenn der Tab wieder sichtbar wird und wenn der Browser wieder online ist, erneut versucht, immer mit demselbenidempotency_key, bis zu 7 Tage lang oder für 12 Versuche.local_only: trueerscheint, wenn es nichts zu senden gibt (zum Beispiel im Moduslocalohnedata-site).
Die Wahl des Besuchers wird in jedem Fall sofort im Browser angewendet; das Ergebnis sagt Ihnen, ob der Server einen Datensatz dazu hat. Die Ausnahme ist COOKIE_POLICY_MISSING: Die Entscheidung wird weder gespeichert noch angewendet.
DocumentApprovalResult
Abschnitt betitelt „DocumentApprovalResult“{ success: true, decision: 'accepted', consent_token: 'ct_…', proof_hash: '…', slug: 'terms-of-service', version: '2.0.0' }{ success: false, slug: 'terms-of-service', version: '2.0.0', error: { code: 'DOCUMENT_VERSION_CHANGED', status: 409, message: '…' } }Dokumentzustimmungen werden nie für später in die Warteschlange gestellt: Ist success nicht true, wurde die Zustimmung nicht erfasst.
Ereignisse
Abschnitt betitelt „Ereignisse“| Ereignis | Payload | Wann |
|---|---|---|
ready | {} | Start abgeschlossen (auch wenn die Konfiguration nicht geladen werden konnte). |
banner:shown | { type } oder { headless: true, reason, config } | Das Banner wurde angezeigt oder sollte — im Headless-Modus — von Ihnen angezeigt werden. |
banner:hidden | { reason } oder { headless: true } | Das Banner wurde geschlossen. |
consent:given | { decision, categories, source } | Eine andere Entscheidung als „alle ablehnen“ wurde lokal gespeichert. |
consent:rejected | { decision, categories, source } | „Alle ablehnen“ wurde lokal gespeichert. |
consent:changed | { oldCategories, newCategories } | Eine Entscheidung hat eine frühere ersetzt. |
consent:withdrawn | { categories, cleanedCookies } | CMP.withdraw() wurde aufgerufen. |
consent:synced | { consent_token, idempotency_key } | Der Server hat einen Datensatz angenommen (sofort oder aus der Warteschlange). |
consent:error | { code, status, message, idempotency_key, pending_sync, final?, reprompt? } | Ein Datensatz konnte nicht zugestellt werden. final: true bedeutet, dass er verworfen wurde. |
document:approved | { slug, version, consentId } | Eine Dokumentzustimmung wurde erfasst. |
document:rejected | { slug, version } | Der Besucher hat ein Dokument abgelehnt. |
document:error | { slug, version, code, status, message } | Ein Dokument konnte nicht geladen werden oder die Zustimmung wurde nicht erfasst. |
scripts:activated | { category, count } | Markierte Skripte einer Kategorie wurden aktiviert. |
config:updated | { content_hash } | Eine neuere Konfiguration hat die zwischengespeicherte ersetzt. |
language:changed | { from, to } | Die Sprache hat sich geändert. |
error | { scope, code, status, message, … } | Jeder der oben genannten Fehler; scope ist config, consent, module oder document. |
consent:given / consent:rejected werden ausgelöst, wenn die Entscheidung im Browser gespeichert ist. Verwenden Sie consent:synced (oder das Promise-Ergebnis), wenn Sie wissen müssen, dass der Server sie hat.
Fehlercodes
Abschnitt betitelt „Fehlercodes“Codes, die das SDK selbst erzeugt:
| Code | Bedeutung |
|---|---|
NOT_READY | Eine Entscheidungsmethode wurde aufgerufen, bevor die Konfiguration geladen war. Rufen Sie sie innerhalb von CMP.ready() auf. |
COOKIE_POLICY_MISSING | Der Website ist kein veröffentlichtes Cookie-Richtlinien-Dokument zugeordnet. Das Banner wird nicht angezeigt, nicht notwendige Skripte bleiben blockiert, und die Entscheidung wird weder gespeichert noch in die Warteschlange gestellt. |
NETWORK_ERROR, TIMEOUT | Keine Antwort von der API (Timeout: 5 s pro Versuch). |
HTTP_<status> | Der Server hat mit einem Fehler geantwortet, der keinen Maschinencode trägt. |
DOCUMENT_VERSION_CHANGED | Die referenzierte Dokumentversion ist nicht mehr die aktive; der Datensatz wurde verworfen. |
PENDING_EXPIRED | Eine Entscheidung in der Warteschlange konnte nicht innerhalb von 7 Tagen zugestellt werden und wurde verworfen. |
MODULE_LOAD_FAILED | Eine Moduldatei (documents oder preferences) konnte nicht geladen werden. Wird auch über das Ereignis error mit scope: "module" gemeldet. |
APPROVAL_TOKEN_REQUIRED | Das Dokument erfordert ein einmaliges Zustimmungstoken und es wurde keines übergeben (wird auch vom Server zurückgegeben). |
CONFIG_UNAVAILABLE | Die Konfiguration konnte nicht geladen werden (wird über das Ereignis error gemeldet). |
UNEXPECTED_ERROR | Alles andere. |
Vom Server zurückgegebene Codes werden unverändert durchgereicht. Die wichtigsten sind auf der Seite zur REST-API aufgeführt — zum Beispiel CONFIG_OUTDATED, SITE_NOT_VERIFIED, ORIGIN_NOT_ALLOWED, RATE_LIMIT_EXCEEDED, CONSENT_LIMIT_EXCEEDED, APPROVAL_TOKEN_INVALID.
Vorübergehende Serverantworten. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) und 429 RATE_LIMIT_EXCEEDED werden automatisch mit demselben idempotency_key wiederholt; das SDK wartet die im Header Retry-After angegebene Zeit ab. Ist diese Zeit länger als 5 Sekunden, wartet das SDK nicht innerhalb der Seite: Die Entscheidung bleibt in der lokalen Warteschlange (pending_sync: true) und wird später gesendet. Nach 429 TOO_MANY_INVALID_API_KEYS sendet das SDK während dieses Seitenaufrufs keine weiteren Anfragen, und Entscheidungen in der Warteschlange bleiben erhalten; prüfen Sie den Wert von data-site. Keine dieser Antworten beeinträchtigt Ihre Seite: Das Ereignis error wird ausgelöst, und CMP.ready()-Callbacks werden weiterhin ausgeführt.
Abschnitt betitelt „Vorübergehende Serverantworten. 503 (API_KEY_LOOKUP_UNAVAILABLE, ADMISSION_UNAVAILABLE, QUEUE_OVERLOADED) und 429 RATE_LIMIT_EXCEEDED werden automatisch mit demselben idempotency_key wiederholt; das SDK wartet die im Header Retry-After angegebene Zeit ab. Ist diese Zeit länger als 5 Sekunden, wartet das SDK nicht innerhalb der Seite: Die Entscheidung bleibt in der lokalen Warteschlange (pending_sync: true) und wird später gesendet. Nach 429 TOO_MANY_INVALID_API_KEYS sendet das SDK während dieses Seitenaufrufs keine weiteren Anfragen, und Entscheidungen in der Warteschlange bleiben erhalten; prüfen Sie den Wert von data-site. Keine dieser Antworten beeinträchtigt Ihre Seite: Das Ereignis error wird ausgelöst, und CMP.ready()-Callbacks werden weiterhin ausgeführt.“Erneute Einwilligung und geänderte Dokumentversionen
Abschnitt betitelt „Erneute Einwilligung und geänderte Dokumentversionen“Wann das Banner erneut angezeigt wird. Die gespeicherte Einwilligung merkt sich den Inhalts-Hash der Banner-Konfiguration, für die sie erteilt wurde. Das Banner wird erneut angezeigt, wenn:
- die Einwilligung abgelaufen ist (die Gültigkeitsdauer wird im Dashboard festgelegt),
- sich die Kategorie- / Cookie-Struktur des Banners geändert hat oder
- eine neue Version eines zugeordneten Dokuments veröffentlicht wurde — es sei denn, die Banner-Einstellung
reconsent_on_doc_changeist ausgeschaltet; in diesem Fall lösen nur Strukturänderungen eine erneute Einwilligung aus.
Solange in einer Opt-in-Region eine erneute Einwilligung aussteht, bleibt die bisherige Wahl des Besuchers wirksam, bis er erneut entscheidet.
Ausstehende Entscheidungen und eine geänderte Dokumentversion. Wenn eine Entscheidung nicht zugestellt werden konnte (offline, Seite geschlossen, Serverfehler) und die Dokumentversion, auf die sie verweist, beim erneuten Versuch nicht mehr die aktive ist, geht das SDK wie folgt vor:
- Es fragt beim Server die aktuelle Konfiguration ab und umgeht dabei den Cache;
- ist die Version unverändert (der 409 wurde durch einen kalten Server-Cache verursacht), sendet es denselben Datensatz noch einmal;
- hat sich die Version geändert, verwirft es den Datensatz, entfernt die lokal gespeicherte Einwilligung und zeigt das Banner erneut an (
consent:errormitcode: "DOCUMENT_VERSION_CHANGED",final: true,reprompt: true).
Ein ausstehender Datensatz wird nie mit einer anderen Dokumentversion erneut gesendet: Der Besucher hat diese Version nicht gesehen.
Regionen, Regulierungsprofile und Verhaltens-Flags
Abschnitt betitelt „Regionen, Regulierungsprofile und Verhaltens-Flags“Die Region des Besuchers wird in dieser Reihenfolge ermittelt: CMP.setRegion() → data-region → das GeoIP-Ergebnis des Servers in der Konfigurationsantwort (detected_region) → eine Schätzung anhand der Browser-Zeitzone → der fest eingestellte Regulierungsmodus des Banners → die strengsten Regeln (DSGVO). Das SDK ruft niemals einen Geolokalisierungsdienst eines Drittanbieters auf.
| Region | Regelwerk | Modell | Verhalten |
|---|---|---|---|
| EU / EWR, Schweiz | gdpr | Opt-in | Banner; markierte Skripte bleiben blockiert, bis sie erlaubt werden. |
| Türkei | kvkk | Opt-in | Wie DSGVO. |
| Vereinigtes Königreich | uk_gdpr | Opt-in | Wie DSGVO (siehe uk_analytics_exemption). |
| Brasilien | lgpd | Opt-in | Wie DSGVO. |
| Südafrika, Kanada, China, Südkorea | popia, pipeda, pipl, pipa | Opt-in | Es werden die Banner-Regeln der DSGVO angewendet. |
| USA | ccpa — nur wenn aktiviert, sonst gdpr | Opt-out / Opt-in | Siehe ccpa_opt_out_enabled. |
| Unbekannt | gdpr | Opt-in | Strengste Regeln. |
none (explizit) | none | — | Kein Banner; alle Skripte werden ausgeführt. |
In jedem Opt-in-Profil hat das Banner immer eine Schaltfläche „Ablehnen“ mit demselben visuellen Gewicht wie „Akzeptieren“, und keine optionale Kategorie ist vorausgewählt — unabhängig davon, was das Banner-Design vorgibt.
Drei Verhaltens-Flags (Banner → Verhaltenseinstellungen im Dashboard, banner_config.behavior in einer lokalen Konfiguration) ändern dies:
| Flag | Standard | Wirkung |
|---|---|---|
uk_analytics_exemption | aus | Nur für Besucher aus dem Vereinigten Königreich: Mit analytics markierte Skripte dürfen vor einer Entscheidung ausgeführt werden. Jede andere Kategorie benötigt weiterhin eine Einwilligung, und sobald der Besucher entschieden hat, gilt seine Entscheidung. |
ccpa_opt_out_enabled | aus | Besucher, die in den USA erkannt werden, erhalten das Opt-out-Modell: Skripte werden standardmäßig ausgeführt, ein Link „Do Not Sell or Share My Personal Information“ wird angezeigt, und ein Global-Privacy-Control-Signal wird einmalig als Opt-out angewendet (consent_type: do_not_sell_opt_out). Ist das Flag aus, erhalten US-Besucher das Opt-in-Banner. |
reload_on_revoke | an | Lädt die Seite neu, wenn ein Besucher eine Kategorie widerruft, deren Skripte auf dieser Seite bereits ausgeführt wurden. Schalten Sie es nur aus, wenn Ihre Tags selbst auf Änderungen der Einwilligung reagieren. |
Google Consent Mode v2
Abschnitt betitelt „Google Consent Mode v2“Wenn Consent Mode eingeschaltet ist, erstellt das SDK window.dataLayer und eine Funktion gtag, falls sie nicht existieren, und sendet:
gtag('consent', 'default', { …all denied…, wait_for_update: 500 })während des Starts,gtag('consent', 'update', { … })nach jeder Entscheidung und bei jedem Seitenaufruf mit gespeicherter Einwilligung.
| Signal | Erteilt, wenn diese Kategorie erlaubt ist |
|---|---|
ad_storage, ad_user_data, ad_personalization | marketing |
analytics_storage | analytics |
functionality_storage, personalization_storage | preferences |
security_storage | immer |
Das SDK sendet außerdem die Data-Layer-Ereignisse hashentry_consent_default und hashentry_consent_update.
Einrichtung:
- Schalten Sie Google Consent Mode für das Banner im Dashboard ein, oder fügen Sie dem Script-Tag
data-consent-mode="true"hinzu. - Platzieren Sie das HashEntry-Script-Tag oberhalb Ihres Google-Tags / GTM-Snippets.
- Wenn der Befehl
defaultbeim allerersten Seitenaufruf eines Besuchers vor den Google-Tags stehen muss, verwenden Siedata-consent-mode="true"und laden Siecmp.jsohneasync. Die Dashboard-Einstellung kommt mit der Konfiguration an, die bei einem ersten Besuch asynchron geladen wird; bei späteren Besuchen wird sie während des Starts aus der zwischengespeicherten Konfiguration gelesen.
Consent Mode sendet nur Signale. Tags, die nicht von Consent Mode gesteuert werden, müssen weiterhin wie oben beschrieben für die Blockierung markiert werden.
Headless-Modus
Abschnitt betitelt „Headless-Modus“Mit data-headless="true" rendert das SDK nichts. Es lädt weiterhin die Konfiguration, blockiert markierte Skripte, aktualisiert Consent Mode und erfasst Entscheidungen.
CMP.on('banner:shown', ({ headless, reason, config }) => { if (headless) openMyBanner(config); // reason: no_consent | expired | reconsent | withdrawn | api | opt_out});
myAcceptButton.onclick = async () => { const result = await CMP.accept({ analytics: true, marketing: false }); if (!result.success && !result.pending_sync) showError(result.error);};Betriebsmodi
Abschnitt betitelt „Betriebsmodi“| Modus | Konfigurationsquelle |
|---|---|
remote | Nur der Server. data-site ist erforderlich. |
local | Nur die Seite (CMP.setConfig, data-config oder <script type="application/json" id="cmp-config">). |
local-fallback (Standard) | Der Server; ist er nicht erreichbar, die Konfiguration der Seite. |
Der Modus legt nur fest, woher die Konfiguration kommt. Entscheidungen werden in jedem Modus an den Server gesendet, solange data-site gesetzt ist. Im Modus local ohne data-site bleiben Entscheidungen nur im Browser (local_only: true).
Eine lokale Konfiguration hat dieselbe Struktur wie die Serverantwort:
<script type="application/json" id="cmp-config">{ "banner_config": { "layout": "bottom_bar", "theme": { "primary_color": "#2563EB", "font_family": "system", "theme_mode": "auto" }, "behavior": { "show_widget": true, "show_reject_button": true, "show_settings_button": true }, "categories": [ { "key": "necessary", "required": true, "default": true }, { "key": "analytics", "required": false, "default": false, "cookies": [{ "name": "_ga", "provider": "Google", "type": "cookie", "duration": "2 years" }] } ], "languages": { "default": "en", "translations": { "en": { "title": "Cookie preferences", "description": "We use cookies to measure how the site is used.", "accept_button_text": "Accept all", "reject_button_text": "Reject all", "settings_button_text": "Manage preferences", "save_selected_text": "Save selection", "modal_title": "Cookie settings", "always_active_text": "Always active", "categories": { "necessary": { "label": "Necessary", "description": "Required for the site to work." }, "analytics": { "label": "Analytics", "description": "Visitor statistics." } } } } } }}</script><script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" data-mode="local" async></script>Ist data-site gesetzt, fragt das SDK beim Start einmal das Cookie-Richtlinien-Dokument vom Server ab, weil eine Einwilligung auf dessen Version verweisen muss. Ist keine Richtlinie zugeordnet, wird das Banner nicht angezeigt (COOKIE_POLICY_MISSING). Soll das Banner auch dann erscheinen, wenn der Server nicht erreichbar ist, nehmen Sie documents (die Cookie-Richtlinie und ihre Version) in die Seitenkonfiguration auf.
Sprachen und Texte
Abschnitt betitelt „Sprachen und Texte“Alle Banner-Texte (Titel, Beschreibung, Schaltflächen, Kategorienamen) stammen aus der Banner-Konfiguration — sie sind nicht Teil des Skripts.
Das SDK enthält ein kleines eingebautes Wörterbuch, nur auf Englisch und Türkisch, für Texte, die zu seiner eigenen UI gehören: den „Do Not Sell“-Dialog, die Schaltflächen und die Fehlerzeile der Dokumentzustimmung, die Überschriften der Cookie-Tabelle und die Schaltfläche zum Schließen. In jeder anderen Sprache fallen diese Texte auf Englisch zurück, sofern Sie sie nicht bereitstellen:
CMP.setLocale('de', { document: { approve: 'Ich stimme zu', reject: 'Ablehnen', saving: 'Wird gespeichert…', error: 'Ihre Zustimmung konnte nicht gespeichert werden. Bitte versuchen Sie es erneut.' }, ccpa: { link: '…', description: '…', cancel: 'Abbrechen', optOut: 'Widersprechen' }, cookies: { name: 'Name', provider: 'Anbieter', type: 'Typ', duration: 'Dauer', purpose: 'Zweck', category: 'Kategorie', count: '{n} Cookies', empty: 'Keine Cookies registriert.' }});Eine Konfiguration kann dieselben Schlüssel pro Sprache unter languages.translations.<lang>.sdk_texts enthalten.
Bundles und bei Bedarf geladene Module
Abschnitt betitelt „Bundles und bei Bedarf geladene Module“| Datei | Inhalt | Geladen |
|---|---|---|
cmp.js | Kern und Cookie-Einwilligung | Durch Ihr Script-Tag. |
cmp-documents.<hash>.js | Dokumentzustimmung (showDocumentApproval, approveDocument) | Durch cmp.js, beim ersten Aufruf einer dieser Methoden. |
cmp-preferences.<hash>.js | Einstellungszentrum, Tabelle mit Cookie-Details, Bestätigungsdialog „Do Not Sell“ | Durch cmp.js, wenn der Besucher eines davon zum ersten Mal öffnet. |
Sie fügen nie ein zweites Script-Tag hinzu. Eine Website, die nur das Cookie-Banner verwendet, lädt das Dokumentmodul nie herunter.
- Die Moduldatei wird vom selben Ort wie
cmp.jsangefordert (abgeleitet aus demsrcdes Skripts). - Um die kurze Verzögerung beim ersten Aufruf zu vermeiden, laden Sie es vorab:
data-modules="documents". - Aufrufe, die erfolgen, bevor das Modul angekommen ist, warten einfach darauf. Kann es nicht geladen werden, wird die Methode mit
success: falseunderror.code = "MODULE_LOAD_FAILED"aufgelöst; der nächste Aufruf versucht es erneut. - Kann das Modul
preferencesnicht geladen werden, bleibt das Banner mit seinen Schaltflächen zum Akzeptieren und Ablehnen sichtbar, das Ereigniserrorwird mitscope: "module"undcode: "MODULE_LOAD_FAILED"ausgelöst, und der nächste Klick versucht es erneut. Um das Einstellungszentrum ohne Verzögerung zu öffnen, laden Sie das Modul vorab:data-modules="preferences". - Der Dateiname enthält einen Inhalts-Hash, der beim Build in
cmp.jseingebettet wird, sodasscmp.jsimmer das Modul anfordert, das zusammen mit ihm gebaut wurde.
Content Security Policy. Das Modul wird mit einem <script>-Element vom selben Ursprung wie cmp.js geladen; das SDK verwendet weder eval noch Inline-Skripte. Für Skripte ist der Ursprung des SDK alles, was Sie benötigen:
script-src https://tool.hashentry.com;connect-src https://system.hashentry.com;- Das SDK gestaltet seine UI mit
<style>-Elementen innerhalb seines eigenen Shadow Root. Wenn Ihre Richtliniestyle-srceinschränkt, erlauben Sie entweder'unsafe-inline'für Styles oder verwenden Sie eine Nonce: Setzen Sie die Nonce auf dascmp.js-Tag (<script nonce="…" …>), und das SDK kopiert sie auf die Style-Elemente und auf das Script-Tag des Moduls, das es erzeugt. - Mit
script-src 'strict-dynamic'und einer Nonce auf demcmp.js-Tag ist das Modulskript erlaubt, ohne dass der Ursprung aufgeführt werden muss. - Der Dialog zur Dokumentzustimmung rendert das Dokument in einem
iframemit Sandbox und ohnesrc; Skripte innerhalb des Dokuments werden nicht ausgeführt.
Subresource Integrity. https://tool.hashentry.com/cmp.js wird an Ort und Stelle aktualisiert, wenn eine neue SDK-Version veröffentlicht wird, sodass ein integrity-Attribut für diese URL bei der nächsten Veröffentlichung nicht mehr passen würde. Wenn Sie SRI benötigen, hosten Sie eine geprüfte Kopie von cmp.js zusammen mit den cmp-documents.*.js / cmp-preferences.*.js-Dateien desselben Builds auf Ihrem eigenen Ursprung und setzen Sie integrity auf Ihr eigenes Tag.
Self-Hosting. Kopieren Sie cmp.js, cmp-documents.<hash>.js, cmp-preferences.<hash>.js, cmp-preferences.js und cmp-documents.js aus demselben Build in einen Ordner. Liegen die Moduldateien an anderer Stelle, setzen Sie data-module-base.
First-Party-Proxy
Abschnitt betitelt „First-Party-Proxy“Um API-Anfragen über Ihre eigene Domain zu senden, setzen Sie data-api-url (oder CMP.setApiUrl) auf einen Pfad oder eine URL auf Ihrer Seite und leiten Sie diese an die HashEntry-API weiter, ohne den Pfad unterhalb des Präfixes zu ändern:
<script src="https://tool.hashentry.com/cmp.js" data-site="YOUR_SITE_API_KEY" data-api-url="/hashentry-api" async></script># /hashentry-api/tool/v1/consents → https://system.hashentry.com/tool/v1/consentslocation /hashentry-api/ { proxy_pass https://system.hashentry.com/; proxy_set_header Host system.hashentry.com; proxy_ssl_server_name on; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;}Die Anfragesignatur umfasst den Pfad /tool/v1/..., daher muss die Upstream-Anfrage mit genau diesem Pfad ankommen. Die erfasste IP-Adresse ist diejenige, die HashEntry sieht; ob die Adresse des Besuchers aus X-Forwarded-For übernommen wird, hängt davon ab, ob der Proxy auf der HashEntry-Seite als vertrauenswürdig eingestuft ist — fragen Sie den Support, bevor Sie sich darauf verlassen.
Was das SDK im Browser speichert
Abschnitt betitelt „Was das SDK im Browser speichert“| Name | Wo | Zweck |
|---|---|---|
_he_consent | First-Party-Cookie | Die Entscheidung des Besuchers (Kategorien, Zeitstempel, Server-Token). |
he_consent_token | localStorage | Kopie derselben Entscheidung. |
he_config_cache | localStorage | Zwischengespeicherte Konfiguration (bis zu 7 Tage, bei jedem Laden im Hintergrund erneut validiert). |
he_pending_consents | localStorage | Entscheidungen, die der Server noch nicht angenommen hat (nach der Übermittlung entfernt; nach 7 Tagen verworfen). |
he_gpc_applied | localStorage | Vermerkt, dass ein GPC-Opt-out einmal angewendet wurde. |
he_sdk_reload | sessionStorage | Schützt die Selbstaktualisierung des SDK vor Neulade-Schleifen. |
Das SDK lädt keine Schriftarten oder sonstigen Ressourcen von Drittanbietern.