# 100 % Abdeckung — ein Weg für alle

Ein Tracking, das bei jedem fünften Besucher schweigt, optimiert die Kampagnen
auf die falschen Leute. Deshalb hat Trackdolphin für jeden Shop denselben
Anspruch: **Jeder Kauf, dem der Käufer zugestimmt hat, kommt an** — in
jedem Browser, mit jedem Werbeblocker, auf jedem Gerät. Der Weg dorthin ist
für alle Shops derselbe; nur die Umsetzung sieht je nach Plattform anders aus.

## Die drei Gegner

**Werbeblocker** arbeiten mit Hostnamen-Listen. Ein Request an
`connect.facebook.net`, `google-analytics.com` oder auch an
`irgendwas.trdph.com` wird blockiert, sobald der Hostname auf einer Liste
steht — und Listen wachsen. Was auf keiner Liste stehen kann, ist die Domain
des Shops selbst: Wer die blockiert, blockiert den Shop.

**Safari** kürzt seit ITP 2.1 jedes per JavaScript gesetzte Cookie auf sieben
Tage — egal, welche Laufzeit das Skript anfragt. Seit 16.4 gilt dasselbe für
Cookies von Subdomains, die per CNAME auf fremde Infrastruktur zeigen. Der
Besucher, der heute über eine Anzeige kommt und in zwei Wochen kauft, ist dann
ein Unbekannter: Der Kauf zählt, die Zuordnung zur Anzeige fehlt. Nur ein
Cookie, das der eigene Server per `Set-Cookie` setzt, behält seine Laufzeit.

**Einwilligung** bleibt, wie sie ist. Trackdolphin umgeht kein Banner und
erfindet keine Zustimmung. Wer Marketing ablehnt, bekommt keine
Besucherkennung, und die Plattformen bekommen von ihm nur, was der
[Consent-Modus](/docs/privacy.md#was-ohne-marketing-einwilligung-passiert)
erlaubt. Das ist keine Lücke in der Abdeckung, sondern die Grenze, die
„100 %“ meint.

## Warum ein CNAME nicht reicht

Die verbreitete Antwort auf Werbeblocker ist eine eigene Tracking-Subdomain:
`td.meinshop.de` zeigt per CNAME auf den Collector. Gegen Hostnamen-Listen
hilft das — bis die Subdomain selbst auf einer Liste landet. Gegen Safari
hilft es seit 16.4 nicht mehr: Safari löst den CNAME auf, erkennt die fremde
Infrastruktur dahinter und behandelt die Cookies wie Third-Party. Sieben
Tage, wieder.

Was Safari nicht kappen kann, ist ein Request an **dieselbe Herkunft**,
beantwortet von **demselben Server**, der auch die Seite ausliefert. Das ist
kein Trick, sondern schlicht ein First-Party-Request. Werbeblocker sehen
dabei nebenbei keinen fremden Hostnamen mehr.

## Der eine Weg: dieselbe Herkunft

Der Browser spricht nur mit der Shop-Domain. Der Shop-Server nimmt die Events
entgegen, ergänzt Besucher-IP und User-Agent, setzt die Besucherkennung
per `Set-Cookie` und reicht alles an den Collector weiter. Der Kauf selbst
kommt ohnehin vom Server — aus der Bestellung, nicht aus dem Browser.

```text
Browser ──► shop.de/…/collect ──► Shop-Server ──► Collector ──► Meta, Google, …
            (dieselbe Herkunft)   (Set-Cookie,      (Dedup,
                                   IP, User-Agent)   Routing)
```

Drei Ausprägungen, ein Prinzip:

### Plugin-Shops: WooCommerce und Shopware

Schon eingebaut, nichts zu tun. Das Plugin läuft auf dem Shop-Server und
bringt die Route mit — bei WooCommerce `/wp-json/td/v1/collect`, bei Shopware
`/td/collect`. Das Snippet des Plugins schickt dorthin, der Server setzt
`_td_vid` und leitet weiter. Antwortet die Route einmal nicht (ein
Sicherheits-Plugin sperrt `/wp-json`), weicht das Snippet für die Sitzung
auf den direkten Collector aus — lieber ein Event ohne Tarnung als keins.

### Shopify

Shopify erlaubt keine eigene Route auf der Shop-Domain — aber einen
**App-Proxy**: Shopify reicht Requests an einen Pfad unter der Shop-Domain
an die App weiter. Das Web Pixel schickt an `https://deinshop.de/a/td/collect`,
Shopify reicht das signiert an Trackdolphin weiter, und der Kauf kommt
ohnehin per Webhook von Shopifys Server. Der Händler richtet nichts ein: Der
Proxy kommt mit der App. Siehe [Schnellstart
Shopify](/docs/quickstart-shopify.md).

### Headless: SvelteKit, Next.js, Nuxt, Astro, Remix

Das SDK bringt die Route mit — `@trackdolphin/sdk/proxy` ist ein
framework-neutraler Handler über Web-Standard `Request`/`Response`, den du
in einer Datei an deine Route hängst. Das Browser-SDK zeigt dann auf `/td`
statt auf den Collector. Beispiele für jedes Framework stehen auf der
[SDK-Seite](/docs/sdk.md#einbindung), der komplette Weg für SvelteKit im
[Schnellstart SvelteKit](/docs/quickstart-sveltekit.md).

## Welcher Shop, welcher Weg

| Shop | Weg | Was du tun musst |
| --- | --- | --- |
| WooCommerce | Plugin-Route `/wp-json/td/v1/collect` | Nichts — Plugin installieren reicht |
| Shopware | Plugin-Route `/td/collect` | Nichts — Plugin installieren reicht |
| Shopify | App-Proxy unter der Shop-Domain, Kauf per Webhook | Nichts — kommt mit der App; Kauf ist heute schon abgedeckt |
| SvelteKit, Next.js, Nuxt, Astro, Remix | Proxy-Route aus `@trackdolphin/sdk/proxy` | Eine Datei anlegen, `init({ endpoint: "/td" })` |
| Andere (Custom, PHP, …) | Eigene Route, die an den Collector weiterreicht — oder die direkte Collector-URL | Route nach dem Vorbild des SDK-Proxys bauen; sonst mit Blocker- und Safari-Verlust leben |

## Was „100 %“ nicht heißt

- **Nicht ohne Einwilligung.** Wer Marketing ablehnt, wird nicht heimlich
  doch gemessen. Der Kauf wird gemeldet, aber ohne Kennungen — und je nach
  [Einstellung](/docs/privacy.md#was-ohne-marketing-einwilligung-passiert)
  gar nicht an die Werbeplattformen.
- **Nicht ohne Server.** Ein rein statisches Frontend ohne Server-Route hat
  nur die direkte Collector-URL. Das funktioniert, aber Werbeblocker und
  Safari holen sich dann ihren Anteil.
- **Nicht rückwirkend.** Besucher, deren Cookie Safari schon gekappt hat,
  bekommen beim nächsten Besuch eine neue Kennung. Ab da hält sie.

Die Abdeckung, die du tatsächlich erreichst, zeigt dir die
[Erkennungsquote](/docs/backfill.md) nach dem Import der Historie — und der
[Wächter](/docs/watchdog.md) meldet, wenn sie einbricht.
