# Fremde Werkzeuge beschriften

In deinem Projekt läuft vermutlich schon eines dieser Werkzeuge: Microsoft Clarity,
PostHog oder Sentry. Alle drei sehen, **was** passiert ist — aber keines weiß,
**woher** der Besucher kam. Werbekanal, Kampagne, Einwilligungsstand und
Bestellwert entstehen serverseitig, in Trackdolphin.

Das SDK schreibt dieses Wissen als Merkmal in das laufende fremde Werkzeug.
Danach kannst du dort nach Dingen filtern, die es aus eigener Kraft nie kennen
könnte:

> „Zeig mir nur Aufzeichnungen aus bezahltem Google-Verkehr mit einem Warenkorb
> zwischen 250 und 500 Euro."
>
> „Zeig mir nur die Fehler, die bezahlten Traffic treffen."

## Was gesetzt wird

Für alle drei dasselbe Vokabular:

| Merkmal | Beispielwerte | Wann |
|---|---|---|
| `td_channel` | `google_paid`, `meta_paid`, `organic_search`, `direct`, `referral_blog.example.com` | beim ersten Seitenaufruf |
| `td_campaign` | `sommer_sale` | wenn ein `utm_campaign` vorliegt |
| `td_consent` | `granted`, `partial`, `denied` | sobald der Besucher entschieden hat |
| `td_value_band` | `100_250` | beim Kauf |

Der Kanal wird nach Verlässlichkeit abgeleitet: Eine Klick-ID (`gclid`, `fbclid`,
`msclkid` …) schlägt jedes UTM, UTM schlägt die Verweisadresse. Eine `gclid` ist
ein Beleg, ein `utm_source=google` ist eine Behauptung, die jeder Newsletter
tragen kann.

## Einrichtung

**Für die Beschriftung: keine.** Findet das SDK eines der Werkzeuge im Fenster,
beschriftet es die Sitzung. Ist keines da, passiert nichts.

Die Werkzeuge selbst bindest du wie gewohnt bei deren Anbieter ein — wir liefern
sie nicht aus und ersetzen ihre Einrichtung nicht:

| Werkzeug | Einbindung | Danach von uns |
|---|---|---|
| Microsoft Clarity | Clarity-Tag im Theme oder über die Shopify-App von Microsoft | nichts zu tun |
| PostHog | `posthog-js` per Snippet oder npm | nichts zu tun; für den Sprung in die Aufzeichnung einmalig das Projekt hinterlegen (siehe unten) |
| Sentry | `@sentry/browser` per npm oder CDN-Loader | nichts zu tun |

Wichtig ist nur die Reihenfolge nicht: Wird das Werkzeug erst nach unserem
`init()` geladen — etwa weil ein Einwilligungsbanner es zurückhält —, fassen wir
von selbst nach.

Einzeln abschaltbar:

```js
import { init } from "@trackdolphin/sdk";

init({
  endpoint: "/td",
  clarity: false,  // Standard: true
  posthog: false,  // Standard: true
  sentry: false,   // Standard: true
});
```

## Wir laden nichts, und wir holen nichts zurück

Das ist die wichtigste Eigenschaft: Trackdolphin liefert **kein** fremdes Skript
aus. Wir sprechen ein globales Objekt nur an, wenn dein Projekt es selbst
eingebunden hat. Und wir holen keine Daten zurück — kein Schlüssel, kein OAuth,
keine Ratenlimits, keine fremden Ausfälle in deinem Betrieb.

Der Grund ist praktisch. Fremde Tracking-Skripte verändern Browser-Prototypen und
brechen damit gelegentlich Seitencode; `clarity-js` etwa hat das wiederholt getan.
Würden wir ein solches Skript ausliefern, kämen diese Fehler bei dir als
Trackdolphin-Fehler an. Deine Projekte bleiben deine, deine Vertragsverhältnisse
auch.

## Kein Personenbezug

Es gehen ausschließlich nicht personenbezogene Werte raus. Keine
Besucherkennung, keine Bestellnummer, keine E-Mail, kein Hash davon. Das ist
nicht Vereinbarung, sondern Bauweise: Die Funktion, die die Merkmale bildet,
nimmt nur Attributionsdaten, den Einwilligungsstand und eine Zahl entgegen — es
gibt keinen Weg, ihr eine Kennung zu übergeben.

Auch der Bestellwert geht als **Band** raus (`100_250`), nie als Betrag. Ein
exakter Betrag wäre zusammen mit einem Zeitstempel ein Wiedererkennungsmerkmal,
ein Band ist es nicht.

Gilt in deiner Einbindung `requireConsent`, wird vor der Entscheidung des
Besuchers nichts gesetzt — dieselbe Linie wie bei den Events.

---

## Microsoft Clarity

Merkmale erscheinen unter **Recordings → Filters → Custom tags**.

Zwei Eigenheiten, die du kennen solltest:

**Ein neues Merkmal braucht 30 Minuten bis 2 Stunden**, bis es in der
Filterliste auftaucht. In den Ereignisdetails einer einzelnen Aufzeichnung
siehst du es sofort. Wundere dich also nicht, wenn direkt nach dem Einbau noch
nichts zum Filtern da ist.

**Jedes Merkmal wird genau einmal je Sitzung gesetzt.** Clarity überschreibt
einen Wert nämlich nicht, sondern hängt ihn an — eine Sitzung stünde sonst
gleichzeitig unter zwei Kanälen im Filter. Deshalb wird `td_consent` erst
geschrieben, wenn eine Entscheidung vorliegt, statt vorläufig gesetzt zu werden.

Wer sicherstellen will, dass ausgerechnet die Sitzungen mit Kauf erhalten
bleiben — Clarity behält 100.000 Aufzeichnungen je Projekt und Tag und
stichprobt darüber —, schaltet das dazu:

```js
init({ endpoint: "/td", clarityUpgradeOnPurchase: true }); // Standard: false
```

Standardmäßig aus, weil der Aufruf die Aufzeichnungstiefe erhöht. Mehr Daten zu
erheben ist eine Entscheidung des Betreibers, nicht unsere.

> **Zur Einordnung:** Microsoft ist bei Clarity eigener Verantwortlicher, nicht
> dein Auftragsverarbeiter, und Clarity ist nicht vom allgemeinen Microsoft-DPA
> erfasst. Wer Clarity einsetzt, trifft diese Entscheidung selbst und muss sie in
> seiner Datenschutzerklärung abbilden. Unsere Merkmale ändern daran nichts.

## PostHog

Die Merkmale gehen als **Super-Properties** raus und hängen damit an jedem
folgenden Event der Sitzung. Filtern kannst du sie in Insights **und** in der
Replay-Liste; die Verknüpfung läuft über PostHogs `$session_id`.

Anders als bei Clarity überschreibt PostHog bei gleichem Schlüssel — wir dürfen
also jederzeit mit dem vollen Satz nachfassen, etwa wenn die Einwilligung erst
später entschieden wird.

### Sprung in die Aufzeichnung

Läuft PostHog mit Session Replay, liest das SDK dessen Sitzungskennung aus und
schickt sie mit. In der Personen-Ansicht steht dann bei jedem Ereignis ein Link
**„ansehen"** direkt in die Aufzeichnung dieses Moments — die Frage „warum ist
der Kauf hier verlorengegangen?" wird ansehbar statt erratbar.

Damit das greift, hinterlege einmalig dein PostHog-Projekt unter
**Einstellungen → Session Replay**: den Oberflächen-Host — die Adresse, unter
der du PostHog im Browser öffnest, also `https://eu.posthog.com` für die
EU-Cloud, `https://us.posthog.com` für die US-Cloud, **nicht** den `api_host`
aus dem Snippet — und das Segment hinter `/project/` aus PostHogs Adresszeile.

Ohne diese beiden Felder beschriften wir PostHog weiterhin, verlinken aber
nicht.

Wir bauen die Adresse bewusst selbst, statt PostHogs `get_session_replay_url()`
zu nehmen: Die Methode leitet den Host aus `api_host` ab, und wer PostHog über
eine eigene Proxy-Route schickt — bei Trackdolphin-Kunden der Normalfall — bekäme
dort einen Host, der ins Leere zeigt.

Die Kennung wird nur mitgeschickt, wenn PostHog fertig geladen war **und**
tatsächlich aufgezeichnet hat. Sonst bleibt sie weg: Ein Link auf eine
Aufzeichnung, die es nicht gibt, wäre schlimmer als kein Link.

## Sentry

Die Merkmale gehen als **Tags** raus und hängen an allen folgenden Ereignissen
der Seite. In der Fehlersuche filterst du damit über `td_channel:google_paid` —
und siehst, ob ein Fehler ausgerechnet den bezahlten Verkehr trifft. Auch
Sentrys Session Replay lässt sich danach filtern.

Bereits gesendete Fehler bleiben unverändert; Merkmale werden erst beim
Aufbereiten eines Ereignisses zusammengeführt.

Bei Einbindung über das CDN-Loader-Skript setzen wir die Merkmale über
`Sentry.onLoad()`. Das ist nötig, weil `setTag` im Loader-Stub gar nicht
enthalten ist — ein direkter Aufruf davor würde werfen. Für die npm-Einbindung
ist derselbe Pfad ein sofortiger Aufruf, das SDK exportiert `onLoad` ebenfalls.

## Grenzen

Werte werden auf 120 Zeichen gekürzt. Das liegt unter der jeweils strengsten
Grenze der drei — Sentry erlaubt 200 Zeichen und kürzt selbst **nicht**, Clarity
erlaubt 254 und **verwirft** zu lange Werte still statt sie zu kürzen. Ein zu
langer Kampagnenname ergäbe dort also gar kein Merkmal.

Die Schlüsselnamen sind fest und tragen alle das Präfix `td_`. Das ist Absicht:
PostHog drosselt die Anlage neuer Property-Definitionen, und wer Schlüssel
dynamisch bildet, dessen neue Schlüssel erscheinen irgendwann gar nicht mehr im
Filter.

Ein Sprung in eine einzelne **Clarity**-Aufzeichnung ist nicht möglich — Clarity
veröffentlicht für das Web keine Adressform für eine einzelne Sitzung. Dort führt
der Weg über den Filter im Clarity-Dashboard. Nur PostHog gibt die Sitzungskennung
clientseitig heraus.
