adconsent

SDK Dokumentation

Weitere Anleitungen: Debug-Konsole (cmpconsole) · Debug console (English)

# adconsent JavaScript SDK

Diese Dokumentation beschreibt die Einbindung von adconsent (`/cmp/v1/cmp.js`), das Blockieren von Scripts und Iframes bis zur Einwilligung, Google Consent Mode v2, die IAB-Schnittstellen `__tcfapi`/`__gpp` sowie das JavaScript-API `window.cmp`.

## Installation (Snippet)

**Das Snippet muss als Erstes im `<head>` stehen.** Tags, die im HTML vor der CMP stehen, werden vom Browser sofort geladen und können nicht mehr automatisch blockiert werden.

```html
<!-- 1. TCF-Stub (synchron): stellt window.__tcfapi und den Frame
        iframe[name=__tcfapiLocator] sofort bereit -->
<script src="https://IHRE-CMP-DOMAIN/cmp/v1/stub.js"></script>
<script>
  // 2. Konfiguration + Befehls-Queue
  window.cmp = window.cmp || { q: [] };
  window.__CMP_BASE__ = {
    apiBase: "https://IHRE-CMP-DOMAIN",
    propertyKey: "PROPERTY_PUBLIC_KEY"
  };
  // 3. Google Consent Mode v2: Standard "denied" bis zur Entscheidung
  window.dataLayer = window.dataLayer || [];
  function gtag(){ dataLayer.push(arguments); }
  gtag("consent", "default", {
    ad_storage: "denied",
    ad_user_data: "denied",
    ad_personalization: "denied",
    analytics_storage: "denied",
    functionality_storage: "denied",
    personalization_storage: "denied",
    security_storage: "granted",
    wait_for_update: 500
  });
</script>
<!-- 4. CMP (asynchron) -->
<script src="https://IHRE-CMP-DOMAIN/cmp/v1/cmp.js" async></script>
```

Das fertige Snippet mit Ihrer Domain und Ihrem Property-Key finden Sie eingeloggt oben auf dieser Seite bzw. in den Property-Einstellungen.

Aufrufe, bevor `cmp.js` geladen ist, werden in der Queue `cmp.q` gesammelt und danach ausgeführt, z. B. `cmp.q.push(["show"])`.

Das Land des Besuchers wird serverseitig ermittelt. Zum Testen eines anderen Landes: `window.__CMP_BASE__.country = "US"` (nur für Tests verwenden).

## Manuelles Blocking

```html
<script type="text/plain" data-cmp-vendor="755" src="https://example.com/tag.js"></script>
<script type="text/plain" data-cmp-custom="hotjar">/* inline */</script>
<script type="text/plain" data-cmp-purposes="1,3" src="…"></script>

<iframe data-cmp-src="https://www.youtube.com/embed/…" data-cmp-custom="youtube"></iframe>
```

- `data-cmp-vendor`: IAB-Vendor-ID aus der Global Vendor List (GVL).
- `data-cmp-custom`: Key eines Custom Vendors aus dem Admin.
- `data-cmp-purposes`: IAB-Zweck-IDs (kommagetrennt); alle müssen eingewilligt sein.

Nach der Einwilligung werden Scripts neu erzeugt (damit sie ausgeführt werden); Attribute und Reihenfolge bleiben erhalten. Blockierte Iframes zeigen bis dahin einen Platzhalter mit „Inhalt laden“.

## Auto-Blocking

Scripts und Iframes, die nachträglich per JavaScript eingefügt werden (z. B. durch einen Tag-Manager), werden automatisch zurückgehalten, wenn ihre Domain zu einem Vendor ohne Einwilligung gehört (Domains der Custom Vendors bzw. bekannte Tracker-Domains). Nach der Einwilligung werden sie freigegeben. Nach Ablehnen oder Widerruf werden bekannte Cookies der nicht freigegebenen Vendoren gelöscht (Namen/Muster aus der Vendor-Konfiguration).

**Grenzen:** Tags, die im HTML vor der CMP stehen, sind nicht stoppbar. Bild-Pixel (`<img>`) starten ihren Request bereits beim Setzen der Adresse – erzeugen Sie Pixel aus einem blockierten `<script type="text/plain" data-cmp-vendor="…">`.

## API (`window.cmp`)

| Methode | Beschreibung |
|---------|--------------|
| `consentAll()` | Alle Zwecke/Vendoren akzeptieren (gleicher Ablauf wie der Button: TC-String, Speicherung, Consent-Nachweis, Google Consent Mode, Freigabe blockierter Inhalte) |
| `declineAll()` | Alle ablehnen / Opt-out |
| `show()` / `open()` | Banner bzw. Einstellungen erneut öffnen (`open` ist ein Alias) |
| `getConsent()` | Aktueller Stand: purposes, vendors, customVendors, regime, tcString, gppString, … |
| `hasConsent(vendorIdOrCustomKey)` | `cmp.hasConsent(755)` oder `cmp.hasConsent("hotjar")` |
| `on(event, cb)` / `off(event, cb)` | Events: `ready`, `consent`, `shown`, `hidden` |
| `setLanguage(lang)` | Sprache wechseln (z. B. `"fr"`) |
| `console()` / `console(false)` | Debug-Konsole öffnen / schließen – siehe unten |

### Einstellungen erneut öffnen (Pflicht nach TCF-Policy)

Nutzer müssen ihre Wahl jederzeit ändern können. Binden Sie auf **jeder Seite** (z. B. im Footer) einen Link ein:

```html
<a href="#" data-adconsent-open>Cookie-Einstellungen</a>
<!-- oder per JS -->
<button type="button" onclick="cmp.open()">Datenschutz-Einstellungen</button>
```

Jedes Element mit dem Attribut `data-adconsent-open` öffnet beim Klick den Dialog (auch dynamisch nachgeladene Elemente).

### Beispiele

```js
cmp.on("ready", () => console.log(cmp.getConsent()));
cmp.on("consent", (snap) => console.log("consent", snap));
document.querySelector("#accept").onclick = () => cmp.consentAll();
document.querySelector("#privacy").onclick = () => cmp.show();
```

## Debug-Konsole (cmpconsole)

Zum Prüfen einer Einbindung: Seite mit `?cmpconsole` oder `#cmpconsole` aufrufen (oder `cmp.console()`). Die Konsole zeigt Regime, Einwilligung inkl. dekodiertem TC-String, alle blockierten und freigegebenen Elemente mit Vendor und Blocking-Methode, noch nicht zugeordnete Third-Party-Domains und ein Ereignis-Log. Schließen über ✕, `cmp.console(false)` oder `?cmpconsole=0`.

Ausführliche Anleitung: /docs/cmpconsole (English: /docs/cmpconsole?locale=en)

## `__tcfapi` / `__gpp`

- EU/EWR, UK und Schweiz: `__tcfapi` gemäß IAB TCF v2.3 CMP-API-Spezifikation (Befehle und Rückgabewerte siehe https://github.com/InteractiveAdvertisingBureau/GDPR-Transparency-and-Consent-Framework). Der synchrone Stub (`/cmp/v1/stub.js`) stellt `__tcfapi` und den Locator-Frame `iframe[name=__tcfapiLocator]` sofort bereit, damit Ad-Tags – auch in Iframes per `postMessage` – die CMP von Anfang an finden. Fehlt `stub.js`, legt `cmp.js` beides beim Laden selbst an.
- Testumgebung: adconsent verwendet bis zur Registrierung bei IAB Europe die Test-CMP-ID `999`.
- USA (`gpp_us`): `__gpp` mit US-National-Section (Opt-out). Ein gesetztes Global Privacy Control (`navigator.globalPrivacyControl`) wird automatisch als Opt-out berücksichtigt. Banner mit „Do Not Sell or Share“.

## Google Consent Mode v2

Standard `denied` (mit `wait_for_update`) im Snippet. Nach der Entscheidung sendet adconsent `gtag('consent','update',…)` gemäß der Zuordnung in den Property-Einstellungen (`ad_storage`, `analytics_storage`, …). Für Regionen ohne Opt-in-Pflicht ist der Standardwert (`granted`/`denied`) konfigurierbar.

## Google Tag Manager

adconsent vor dem GTM-Container laden und die Consent-Mode-Defaults im Snippet setzen. Tags an die Consent-Prüfung von GTM bzw. an `cmp.hasConsent(…)` koppeln oder über blockierte Domains laufen lassen.

## Regime

| Regime | Länder | Modell |
|--------|--------|--------|
| `tcf_eu` | EU/EWR | Opt-in (IAB TCF) |
| `tcf_uk` | Vereinigtes Königreich | Opt-in (IAB TCF, UK-Texte) |
| `ch` | Schweiz | Opt-in (IAB TCF) |
| `gpp_us` | USA | Opt-out (GPP, „Do Not Sell or Share“) |
| `notice_only` / `none` | übrige Länder | pro Property konfigurierbar |

## Sprache

Automatisch aus der Browsersprache bzw. `<html lang>`, sonst die Standardsprache der Property. Die Zweck-Texte stammen aus den offiziellen IAB-Übersetzungen; Banner-Texte lassen sich pro Sprache im Admin anpassen.

## Cookie-Declaration

Öffentliche Cookie-Liste Ihrer Property einbetten – per Iframe (HTML): `https://IHRE-CMP-DOMAIN/c/PROPERTY_KEY/cookie-declaration`

oder per JSON und eigenem Markup:

```html
<div id="cmp-cookie-declaration"></div>
<script>
  fetch("https://IHRE-CMP-DOMAIN/c/PROPERTY_KEY/cookie-declaration.json?lang=de")
    .then((r) => r.json())
    .then((data) => {
      const table = document.createElement("table");
      for (const c of data.cookies) {
        const tr = table.insertRow();
        for (const v of [c.name, c.vendor, c.purpose, c.duration, c.description]) {
          tr.insertCell().textContent = v || "";   // textContent: kein HTML einschleusen
        }
      }
      document.getElementById("cmp-cookie-declaration").appendChild(table);
    });
</script>
```

## Troubleshooting

1. Banner erscheint nicht → Ist eine Konfiguration veröffentlicht? Lädt `config.json` mit Status 200 (Netzwerk-Tab)? Die Debug-Konsole (`?cmpconsole`) zeigt Fehler im Log.
2. Scripts laufen vor der Einwilligung → Steht das Snippet als Erstes im `<head>`? Tag manuell markieren; die Debug-Konsole zeigt Methode und Status jedes Elements.
3. Queue greift nicht → Steht `window.cmp = window.cmp || { q: [] }` vor `cmp.js`?
4. Google Consent Mode bleibt `denied` → Werden `gtag`/`dataLayer` vor der CMP definiert? Zuordnung in den Property-Einstellungen prüfen.
5. Anderes Land testen → Demo-Seite der Property mit `?country=US` aufrufen.