Tracker-Einstellungen
Jede Tracker-Einstellung einer Application, was sie erhebt, und eine kurze PII-Einschätzung.
Jede Application hat eigene Tracker-Einstellungen: Sie legen fest, was das Beacon im Browser des Besuchers tut und was gespeichert wird. Jedes Verhalten ist ein einzelner Schalter, und ein Preset setzt diese Schalter auf einen Ausgangspunkt.
Die Einstellungen liegen an der Application und sind jederzeit umschaltbar. Der Script-Cache wird automatisch invalidiert; du deployst deine Website nicht neu und fasst das <script>-Tag nicht an. Eine Shopify-Application bekommt zusätzlich ein zweites, deutlich kleineres Skript für ihren Checkout, siehe Shopify-Checkout messen. Eine ganz neue Application startet auf dem Preset Standard: Unique-Visitor-Analytics über den am Edge abgeleiteten stitch, Fetch/XHR- und Query-Key-Telemetrie und volle Fehler-Frames, und dabei nichts auf das Gerät des Besuchers geschrieben.
Jede Einstellung hat einen eigenen Abschnitt mit stabilem Anker und endet mit einer PII-Zeile. Das rechtliche Gesamtbild steht unter Consent und TDDDG und auf der Privacy-Seite.
Presets
Ein Preset ist ein Ausgangspunkt, den du beim Anlegen einer Application wählst. Es setzt alle Datenschalter auf einmal; danach ist jeder Schalter unabhängig, und sobald du einen davon änderst, gilt sie als Custom. Neue Applications starten auf Standard. (Legst du eine Application direkt über die API ohne Preset an, greifen die nackten Feld-Defaults, die Minimal entsprechen.)
| Einstellung | Minimal | Standard (Default) | Full |
|---|---|---|---|
collect_sessions | ✗ | ✗ | ✓ |
session_consent | deferred | deferred | immediate |
store_stitch | ✗ | ✓ | ✓ |
collect_query_keys | ✗ | ✓ | ✓ |
collect_error_messages | ✗ | ✗ | ✓ |
collect_error_frames | ✗ | ✓ | ✓ |
collect_fetch_xhr | ✗ | ✓ | ✓ |
| Nichts auf dem Gerät gespeichert | ✓ | ✓ | ✗ (sessionStorage._fms) |
- Minimal erhebt nur Core-RUM: Web Vitals, Fehlertyp und -Count, Device- und Connection-Klasse. Keine Identifier, kein Content, kein Fetch/XHR, und nichts auf dem Gerät des Besuchers. Das ist das Opt-down, wenn du gar keinen Besucher-Identifier willst.
- Standard schaltet alles ein, was keine personenbezogenen Daten enthalten kann: das am Edge abgeleitete
stitch-Besuchersignal, Fetch/XHR-Aggregate, Query-Schlüsselnamen und volle Fehler-Stack-Frames. Weiterhin kein Fehlermessage-Text, keine Query-Werte, keine Session-ID und nichts anderes auf dem Gerät. Darauf startet eine neue Application. - Full schaltet alles ein: eine beim Load geschriebene Session-ID, Fehlermessages und volle Frames, Query-Keys. Es ist das einzige Preset, das auf das Gerät schreibt (
sessionStorage._fms), setzt also voraus, dass du Consent geklärt hast.
collect_query_values_for sowie die Routing-, Retention- und Verwaltungseinstellungen gehören zu keinem Preset; sie haben eigene Defaults und werden an der Application gesetzt.
Consent und TDDDG
Egal was eine Application erhebt: das Beacon greift auf dem Gerät des Besuchers lesend auf mehrere Browser-Schnittstellen zu:
- die Performance API (Navigation, Paint, Layout-Shift, Event- und Long-Animation-Frame-Timings) für Web Vitals und Timing,
- die Network Information API (
navigator.connection) für die Connection-Klasse, - die Viewport-Breite (
window.innerWidth), - die Error- und Unhandled-Rejection-Handler (Fehlertyp und -Count, in jeder Konfiguration erhoben),
- das Flag
navigator.webdriver, das ein automatisiert gesteuerter Browser selbst setzt, womit ein Puppeteer- oder Selenium-Lauf als Bot zählt.
fastmon setzt keine Cookies, in keiner Konfiguration. In der Standard-Konfiguration schreibt es nichts auf das Gerät des Besuchers; nur wenn collect_sessions an ist, schreibt es einen einzigen, tab-gebundenen sessionStorage-Eintrag (die Session-ID). Es speichert keinen langlebigen, seiten- oder geräteübergreifenden Identifikator; die Aggregation erfolgt am Edge.
Welche gespeicherten Felder personenbezogen sind und welche nicht, und wo sich ein Rest nicht vollständig ausschließen lässt, steht unter Privacy → Personenbezogene Daten.
Das Auslesen solcher Schnittstellen kann nach § 25 TDDDG und der ePrivacy-Richtlinie einwilligungsrelevant sein. Die Auslegungen reichen von großzügig (das Auslesen einer Browser-API ist gar kein „Zugreifen auf Informationen" auf dem Endgerät) bis streng (Analyse ist nicht „unbedingt erforderlich", also einwilligungspflichtig). Deutschland und der EDPB tendieren zur strengen Auslegung, und die EDPB-Leitlinien 2/2023 beziehen auch lokal erzeugte Ergebnisse einer Browser-API ein.
Wir halten dem den deutschen Normtext entgegen, der bereits gespeicherte Informationen verlangt, und ordnen Minimal und Standard als einwilligungsfrei ein. Gerichtlich geklärt ist das nicht, ein Restrisiko bleibt.
Die Einschätzung für deine Site triffst du, am besten mit deinem Datenschutzbeauftragten. Wenn du fastmon hinter Consent legst, kategorisiere es in deinem CMP als Analyse / Performance-Messung, nicht als „unbedingt erforderlich". § 25 TDDDG und die DSGVO werden parallel geprüft, die vertragliche Aufteilung steht in unserem AVV (§ 4) und den AGB (§ 7). Unter deiner eigenen Domain betreibst du fastmon ohnehin besser, siehe collector_mode.
Wenn eine Application eine Session-ID schreibt (collect_sessions an), schaltet dein CMP den Gerät-Schreibvorgang nach Consent mit einem einzelnen Call frei:
// In your cookie banner's "Accept" callback, and on every page load
// while consent is granted (most consent managers do this for you):
window.fastmon && window.fastmon.grantConsent && window.fastmon.grantConsent();grantConsent() vergibt die sessionStorage._fms-Session-ID und schaltet ab da die seitenübergreifende Verknüpfung frei. Ruf ihn bei jedem Seitenload auf, solange Consent besteht; die meisten Consent-Management-Plattformen tun das für dich.
Die &&-Guards sind wichtig: Das Beacon lädt asynchron, bei einer schnellen Navigation kann dein Consent-Code also laufen, bevor window.fastmon existiert. Geguarded ist dieser frühe Aufruf ein No-op, und geschrieben wird, sobald der Tracker geladen ist; ohne Guard wirft er einen TypeError. Ob der Schreibvorgang auf den Call wartet oder beim Load passiert, entscheidet session_consent.
Einen Widerruf mitten in der Session gibt es nicht: Die Session-ID liegt im sessionStorage und stirbt mit dem Tab.
Session und seitenübergreifende Verknüpfung
collect_sessions
Schreibt eine Session-ID (_fms) in den sessionStorage des Besuchers, sodass Pageviews desselben Besuchs verknüpfbar werden: seitenübergreifende Journeys, Funnels, Einstiegs- und Ausstiegsseiten, Wiederkehr innerhalb der Session. Die ID liegt im sessionStorage und stirbt beim Schließen des Tabs. Sie ist das Einzige, was das Beacon je auf das Gerät schreibt; aus rührt das ausgelieferte Bundle den sessionStorage gar nicht erst an (der Schreibschritt wird herauskompiliert, statt serverseitig verworfen zu werden), und der Collector erzwingt zur Absicherung eine leere Session-ID. Aus auf dem Standard-Preset, mit dem neue Applications starten; das Preset Full schaltet sie an.
Im Dashboard heißt der Schalter Session-ID speichern und liegt unter Besucher & Sampling. Vor dem Einschalten fragt das Dashboard noch einmal nach.
PII: die Session-ID ist ein Besucher-Identifier, und ihr Schreiben ist der einzige Vorgang, mit dem das Beacon etwas auf dem Gerät ablegt, und damit einwilligungsrelevant nach § 25 Abs. 1 TDDDG (siehe Consent und TDDDG). Für die schlankste Position aus lassen, oder mit session_consent kombinieren, um erst nach Opt-In zu schreiben. Aus getragen enthält eine Zeile keinen Identifier auf dem Gerät.
session_consent
Entscheidet, wann die Session-ID geschrieben wird, und ist nur relevant, wenn collect_sessions an ist. Auf deferred (das Dashboard zeigt das als Session-ID erst nach Consent schreiben) wird der Schreibvorgang aufgeschoben, bis dein CMP window.fastmon.grantConsent() aufruft; bis dahin fließen Beacons weiter, nur ohne Session-ID. Auf immediate wird die ID beim Pageload geschrieben. Reads, Observer und Beacons laufen in beiden Fällen: dieser Schalter gatet nur den Gerät-Schreibvorgang, nie die Erhebung. Default deferred.
PII: das ändert Zeitpunkt und Consent-Posture des Session-Schreibens, nicht die erhobenen Datenkategorien. deferred ist der sichere Default (kein Gerät-Schreiben vor Consent); immediate schreibt beim Load und setzt voraus, dass du dafür eine Rechtsgrundlage hast.
store_stitch
Behält das am Edge abgeleitete stitch-Signal auf der gespeicherten Zeile. stitch ist ein HMAC-SHA256 aus IP, User-Agent und dem Collector-Hash der Application, am Edge berechnet unter einem Salt, das alle 24 Stunden rotiert und den Edge-Speicher nie verlässt. Es liefert dir Unique-Visitor-Counts und besucherbezogene Metriken (Bounce Rate, Seiten pro Besuch, Verweildauer), ohne dass etwas auf dem Gerät liegt. Aus erzwingt der Collector stitch beim Insert leer, sodass die Zeile gar keinen Besucher-Identifier trägt. Gilt für alle Sites der Application. An per Default: das Standard-Preset, mit dem neue Applications starten, speichert es. Die vollständige Konstruktion (Forward Secrecy, ≤24 h Verknüpfbarkeit, Scope pro Application) steht unter Privacy → der am Edge abgeleitete stitch.
PII: stitch ist ein pseudonymer Besucher-Identifier und damit personenbezogenes Datum, verarbeitet nach Art. 6 Abs. 1 lit. f DSGVO mit dokumentierter Interessenabwägung; die Verknüpfbarkeit ist auf rund 24 Stunden begrenzt und nach Salt-Rotation forward-secret. Ihn in deiner Datenschutzerklärung zu benennen, ist Sache des Betreibers.
count_visitors_by
Wählt, nach welchem Identifier das Dashboard eindeutige Besucher zählt, stitch oder session. Reine Reporting-Vorgabe, getrennt von den Erhebungsschaltern, und der Query-Resolver klemmt sie auf das, was die Site tatsächlich speichert (ein Override pro Query ist immer möglich). Default stitch. Gilt für alle Sites der Application.
PII: keine eigene. Sie wählt zwischen bereits über store_stitch und collect_sessions erhobenen Identifiern; sie erhebt und speichert nichts Neues.
URLs und Query-Parameter
collect_query_keys
Behält die Namen der Query-Parameter der Seiten-URL (etwa ?page, ?variant), sodass du Analytics nach parametrisierten Routen aufschlüsseln kannst. Parameter-Werte werden bei der Erhebung immer verworfen, unabhängig von diesem Schalter. Aus verwirft die Query-Strings komplett und speichert nur Origin plus Pfad. An per Default (Teil des Standard-Presets).
PII: gering. Nur Schlüsselnamen bleiben, und die tragen selten besucherspezifische Daten; jeder Wert wird gestrippt, bevor die URL den Browser verlässt. Um einen konkreten Wert zu behalten, musst du ihn explizit über collect_query_values_for freigeben. Ein fester Satz an Ad-Attribution- und Click-ID-Parametern (gclid, gbraid, wbraid, msclkid, fbclid sowie die utm_*- und gad_*-Familien) wird unabhängig von diesem Schalter immer verworfen, Schlüssel und Wert, auf Seiten-URLs wie auf Fetch/XHR-Pfaden: Sie tragen kein Routing-Signal, und ihr Schlüsselsatz ändert sich pro eingehendem Link. Nennst du einen davon in collect_query_values_for, überschreibt das die Regel und der Parameter bleibt.
collect_query_values_for
Eine Opt-in-Allow-List (max. 20 Einträge) von Parameternamen, deren Wert zusätzlich behalten wird, längenbegrenzt. Alles, was nicht auf der Liste steht, verliert seinen Wert weiterhin. Setzt collect_query_keys voraus. Typische Einträge sind nicht-personenbezogene Routing- oder Kampagnenparameter wie page, variant, utm_campaign. Default leer. Nicht Teil eines Presets. Shops, deren Checkout-Schritte sich nur in einem Query-Parameter wie ?step= unterscheiden, tragen diesen Key hier ein, damit der Checkout-Funnel darauf matchen kann. OXIDs cl bleibt auch ohne Eintrag erhalten.
PII: die trägst du. Ein Wert wird nur für exakt die Schlüssel gespeichert, die du auflistest, nie „alle Werte". Listest du einen Parameter mit personenbezogenen Daten auf, hast du dich entschieden, ihn zu speichern.
template_url_ids
Ersetzt ID-artige Pfadsegmente der gespeicherten Seiten-URL durch :id, /order/12345 wird also als /order/:id gespeichert und ausgewertet. Ein Seitenbericht verteilt eine Seite dann nicht mehr über Tausende URLs. Standardmäßig aus, nicht Teil eines Presets. Es ist die Regel, nach der die Fetch/XHR-Pfade längst laufen: numerische, UUID-, lange Hex- und opake Token-Segmente, dazu eine ID in einem sonst festen Segment. Lange Produkt-Slugs bleiben wörtlich.
Die Regel greift beim Ingest und nur für neue Zeilen, ein Bericht über den Umschaltzeitpunkt hinweg zeigt also eine Weile beide Formen. Wieder ausschalten holt die rohen URLs nicht zurück. Das Checkout-Funnel-Matching und der Error-Frame-Strip sehen weiterhin den echten Pfad, der Schalter ändert also nicht, welche Pageviews in einer Funnel-Stufe landen.
PII: diese Einstellung entfernt nur Daten. Eine ID in einem Seitenpfad ist Sache des Betreibers, und das ist der Schalter, der sie aus den Berichten heraushält.
Fehler
Was als Fehler zählt
Der Tracker zählt zwei Populationen getrennt, und sie mischen sich nie:
- JavaScript-Fehler (
errcim Beacon): nicht abgefangene Exceptions und unbehandelte Promise-Rejections. Daraus wird die Fehlerrate gebildet. - Fehlgeschlagene Ressourcen (
frc): ein<img>,<script>oder<link>, das nicht geladen hat. Ein eigenes Signal mit eigener Rate und eigener Liste, denn diese Population wird von Ad-Blockern und Tracking-Schutz dominiert und nicht von Defekten der Seite. Siehe Fehlgeschlagene Ressourcen.
Beide Zähler erfassen jedes Vorkommen und stoppen bei 1000 pro Pageview. Ein gespeicherter Zähler von genau 1000 heißt „1000 oder mehr", und jenseits der Grenze erfasst der Tracker keine Signatur mehr, die er auf diesem Pageview noch nicht gesehen hat. Der Collector kappt Beacons älterer Tracker-Builds auf dieselbe Grenze.
Das Beacon trägt bis zu acht sortierte Einträge: die fünf häufigsten JavaScript-Fehler, danach die drei häufigsten fehlgeschlagenen Ressourcen, jeweils innerhalb des eigenen Kanals sortiert. So kann eine Seite voller kaputter Bilder keine echte Exception vom Draht drängen.
First Party heißt: dieselbe registrierbare Domain wie die Seite. Ein Skript, das von cdn.shop.example an eine Seite auf www.shop.example ausgeliefert wird, ist deins, und dieselbe Regel gilt für die Fehlerrate, das First-Party-Flag je Fehler, die Fehler-Herkunft des Pageviews, den Fetch/XHR-Split und die Ressourcen-Liste. Was der Privacy-Strip behält, ist eine strengere Regel und unverändert: ohne collect_error_frames behält ein Frame außerhalb des exakten Seiten-Hosts seinen Host und sonst nichts.
ScriptError ist der Typ für eine Exception, die der Browser maskiert. Ein Skript von einem anderen Origin, geladen ohne CORS-Opt-in, wird als wortwörtliches Script error. gemeldet, ohne Dateiname, Zeile oder Error-Objekt. Es ist damit keiner Datei zuzuordnen und teilte bisher einen Fingerprint mit jedem anderen Fehler ohne Frames. Lade das Skript mit crossorigin="anonymous" von einem Host, der Access-Control-Allow-Origin sendet, dann meldet der Browser den echten Fehler. Setz das Attribut nicht, wo der Header fehlt, denn dann führt der Browser das Skript nicht aus.
Was eine Message sagt
Die Formulierung des Browsers ist für eine ganze Klasse von Fehlern die Diagnose, und sie ist zugleich der einzige Freitext, den der Tracker überhaupt erfasst. Also erkennt der Tracker die Formulierung, statt sie zu senden. Eine Message, die auf eine der Formulierungen der Engines passt, ergibt eine Form aus einer geschlossenen Liste, dazu den Bezeichner, den diese Form benennt, sofern sie einen benennt:
| Form | Was sie sagt |
|---|---|
undefined_read, null_read, undefined_write | ein Property-Zugriff auf nichts, mit dem Property-Namen |
not_defined, not_a_function | ein Name, den es nicht gibt oder der nicht aufrufbar ist, mit dem Namen |
json_empty, json_invalid | eine als JSON geparste Antwort, die leer war oder kein JSON war |
selector_invalid | ein Selektor, den der Browser abgelehnt hat, mit dem Selektor |
readonly_write, stack_overflow, fetch_failed, syntax_unexpected_token | ein Schreibzugriff auf ein Read-only-Property, Endlos-Rekursion, ein Request, der nie fertig wurde, ein Parse-Fehler |
Die Form reist in jeder Konfiguration mit, auch in Minimal. Ein Fehler liest sich also als „uc.setServiceAlias wurde aufgerufen, aber uc existiert an dieser Stelle nicht" auch auf einer Site, die gar keine Messages behält. Die rohe Message reist nur mit eingeschaltetem collect_error_messages.
Wo der rohe Text doch mitreist, bleiben seine Platzhalter lesbar. Ein entferntes Literal behält seine Anführungszeichen, ein Beispiel liest sich also als '*' is not a valid selector, und eine entfernte E-Mail als <email>. Zahlen behalten das nackte *, und eine URL überlebt als Origin plus Pfad, ohne Query, Fragment und numerische Pfad-IDs.
Die Erkennung läuft im Browser, bevor irgendetwas gesendet wird, und genau das macht es überhaupt erst möglich, die Message zu sperren. Der Bezeichner, der mit einer Form mitreist, wird dort ebenfalls geprüft: Ein Identifier muss wie Code aussehen, bei einem Selektor werden die Teile in Anführungszeichen geleert und er wird auf 80 Zeichen begrenzt, alles andere wird verworfen statt gesendet.
Die Form ist Teil des Fehler-Fingerprints, und das macht denselben Fehler über Engines hinweg zu einer Gruppe: Chrome und Safari formulieren denselben Fehler unterschiedlich, und die Gruppierung folgte bisher der Formulierung. Die Signaturen wurden dabei einmalig neu gruppiert, eine Gruppe von davor behält also ihren Key und wächst nicht weiter, während derselbe Fehler unter einem neuen Key wieder auftaucht. Es gibt kein Backfill, denn die Messages, die die neue Gruppierung liest, wurden nie gespeichert.
collect_error_messages
Behält den freien Fehlermessage-Text (Cannot read property 'x' of undefined) zusätzlich zu Fehlertyp, Count und Message-Form. Aus wird die Message nie zusammengebaut: Der Schalter ist ins ausgelieferte Bundle eingebacken, auf einer Site, die sie nicht angefragt hat, kommt sie also gar nicht erst auf den Draht. Aus per Default, auch auf Standard; das Preset Full schaltet es an.
PII: der höchste Freitext-Vektor für personenbezogene Daten im Beacon, und einwilligungsrelevant. Ein stets aktiver Scrubber ersetzt URLs, E-Mails, numerische IDs und Strings in Anführungszeichen vor dem Versand, die Betreiberpflicht bleibt aber bestehen: keine Nutzereingaben in geworfene Fehler. Die Message-Form ist nicht dieses Feld, und sie ist das, was die Dashboards lesen, wo dieser Schalter aus ist. Nur dort einschalten, wo du Consent geklärt hast.
collect_error_frames
Behält volles Stack-Frame-Detail (Script-Pfad plus Zeile und Spalte) für jeden Frame. Aus fallen Frames auf host-only zusammen, außer deine eigenen First-Party-External-Scripts behalten immer Pfad und Zeile/Spalte, damit Bugs im eigenen Code fixbar bleiben. An per Default (das Preset Standard schaltet es an).
PII: eine Code-Position identifiziert den Bug, nicht den Besucher, und sie ist für alle identisch, die ihn treffen, also gilt First-Party-Eigencode-Detail als immer sendbar (sanitisiert auf Origin plus Pfad, ohne Query oder Hash). Volles Detail für Inline- und Third-Party-Frames ist einwilligungsrelevant, weil Zeilennummern in serverseitig personalisiertem HTML sich prinzipiell pro Besucher verschieben könnten, die bleiben also gegatet. Pfade darf der Betreiber nicht mit Identifikatoren bestücken, genau wie Seiten-URLs.
Fetch und XHR
collect_fetch_xhr
Erfasst aggregierte Fetch/XHR-Telemetrie: Aufruf-Counts pro Endpunkt, Dauern, Fehler-Statuscodes und die langsamsten Ausreißer, sodass du siehst, welche deiner eigenen APIs langsam sind oder fehlschlagen. Ein wiederholter Fehler mit demselben Status auf demselben Endpunkt schickt ein einziges fetch_xhr_update; die Wiederholungen erhöhen nur den Fehlerzähler, den das nächste Beacon trägt. Wird beim Rendern ins ausgelieferte Bundle gebacken. Aus unterdrückt die Fetch/XHR-Erhebung komplett, inklusive des Wrappers. An per Default (das Preset Standard schaltet es an). Der Checkout-Funnel liest seine Warenkorb-Interaktionen aus dieser Telemetrie (ein POST an einen bekannten Warenkorb-Endpunkt); ist sie aus, bleiben die Interaktionszahlen leer, während die URL-Stufen weiter funktionieren.
Eine neue Application speichert die Aufrufe eines Viertels ihrer Besucher, siehe Fetch- und XHR-Sampling.
PII: Endpunkt-Pfade werden wie die Seiten-URL sanitisiert, und zwar strenger. Der Collector templatisiert sie serverseitig nach: lange Content-Slugs auf :slug, opake Tokens auf :id, Soft-Navigation-Dokument-Fetches auf /:page, und ein Third-Party-Host verliert seine Query komplett. Die Zähler sind aggregierte Zahlen, und der Ziel-Host ist Site-Metadaten. Das eine Restrisiko ist ein alphabetisches Segment wie /users/jane-doe, das die Templatisierung übersteht, dieselbe Betreiberpflicht wie bei Seiten-URLs.
Page-Type
Im Dashboard und auf der API sind das zwei Einstellungen: platform nennt das Shop-System, page_type.body_class schaltet das Lesen ein. pagetype_ruleset leitet sich aus beiden ab. Ein Tag <meta name="fm-page-type"> braucht keine Einstellung. Das Tag, URL-Regeln und die Reihenfolge aller Quellen stehen unter Applications → Page-Type-Detection.
pagetype_ruleset
Ordnet jeden Pageview in einen Page-Type ein (Product, Category, Cart, Checkout und so weiter), für Shop-Systeme, indem die Body-Controller-Klasse des Shop-Frameworks gelesen wird. Standardmäßig aus (""), dann wird nichts aus dem DOM gelesen. Setz es auf eine eingebaute Ruleset (shopware6, shopware5, oxid, magento, woocommerce), und der Tracker extrahiert den Seiten-Token des Frameworks, den der Collector auf eine Page-Type-Kategorie mappt. Ein Server-Timing: pageType-Header hat immer Vorrang. Wo dein Theme eine der Framework-Klassen umbenannt hat, benennst du sie selbst mit pagetype_rules. Pro Site, und auch auf org-weiten Trackern verfügbar. Siehe Server-Timing → Page-Type. Liefert keine andere Quelle etwas, ergibt ein Pfad der Checkout-Stufe cart oder checkout.
PII: das Einzige, was aus dem DOM gelesen wird, ist ein einzelner Framework-Klassen-Token, gematcht über ein ruleset-spezifisches Muster; nie das volle class-Attribut, nie Seiteninhalt oder Formularwerte, und die rohe Klasse verlässt den Browser nie.
Was jede Ruleset erkennt
Jede Ruleset mappt den Page-Controller-Token des Frameworks auf einen aus einem festen Satz von Page-Types (home, product, category, cart, checkout, search, account). Tokens außerhalb dieser Tabelle mappen auf nichts, und der Pageview behält einen leeren Page-Type. Das Mapping liegt im Collector, verbessert sich also ohne erneutes Ausrollen des browser-gecachten Trackers.
| Page-Type | Shopware 6 1 | Shopware 5 | OXID eShop | Magento | WooCommerce |
|---|---|---|---|---|---|
| home | frontend-home-page, is-ctl-navigation is-act-home | is--ctl-index | cl-start | cms-index-index | nicht typisiert 2 |
| product | frontend-detail-page, is-ctl-product* | is--ctl-detail | cl-details | catalog-product-view | single-product |
| category | frontend-navigation-page, is-ctl-navigation* | is--ctl-listing | cl-alist | catalog-category-view | post-type-archive-product, tax-product_cat |
| cart | frontend-checkout-cart-page, is-ctl-checkout* | is--ctl-checkout 3 | cl-basket | checkout-cart-index | woocommerce-cart |
| checkout | frontend-checkout-confirm-page, frontend-checkout-finish-page, frontend-checkout-register-page | als cart gewertet 3 | cl-user, cl-payment, cl-order | checkout-index-index | woocommerce-checkout |
| search | frontend-search-page, is-ctl-search*, is-ctl-suggest* | is--ctl-search | cl-search | catalogsearch-result-index | nicht typisiert 2 |
| account | frontend-account-*, is-ctl-account* | is--ctl-account | cl-account | customer-account-* | woocommerce-account |
1 Jede Zelle nennt zuerst den aktuellen Token: Shopwares is-active-route-*-Klassen ohne das feste Präfix, die Shops seit etwa 6.6 ausgeben und die in 6.8, das die is-ctl-*- und is-act-*-Klassen entfernt, die einzig verbliebene Seiten-Markierung sind. Die is-ctl-*-Tokens dahinter sind der Legacy-Fallback für ältere Shops und im Browser gecachte Tracker, * steht für einen beliebigen Action-Teil. Home braucht das exakte Legacy-Klassenpaar, weil die Startseite wie jede Kategorieseite über den Navigation-Controller rendert. Über die Legacy-Klassen teilen sich Warenkorb und Checkout is-ctl-checkout und melden beide das gröbere cart, und is-ctl-account* deckt die ganze Account-Controller-Familie ab. 2 WooCommerce nutzt für Home- und Suchseiten generische WordPress-Klassen, die zu breit sind, um sie zuverlässig zu typisieren, also bleiben sie untypisiert. 3 Shopware 5 teilt sich einen Controller-Token über Warenkorb- und Bestätigungsschritt, daher melden beide das gröbere cart statt eines geratenen checkout.
pagetype_rules
Benennt die Body-Klassen deines eigenen Themes, für Themes, die umbenannt haben, was das Shop-System ausliefert. Eine eingebaute Ruleset matcht die Klassen ihres Frameworks, ein OXID-Theme mit c-body--details statt des erwarteten cl-details erfasst also gar keinen Page-Type, und nichts sagt das. Jede Regel bildet genau einen exakten Klassennamen auf einen Page-Type ab (home, product, category, cart, checkout, search, account). Standardmäßig leer.
Die Regeln stehen vor der Ruleset, statt sie zu ersetzen, und zwar in beiden Schritten (Token lesen und Token mappen). Du reparierst also den einen Page-Type, den dein Theme umbenannt hat, und die anderen sechs kommen weiter aus der Ruleset. Mit Regeln und leerem pagetype_ruleset liest der Tracker nur die Klassen, die du benannt hast: so bekommt ein Shop-System oder CMS ohne Ruleset überhaupt einen Page-Type. Ein Server-Timing: pageType-Header hat weiterhin vor beidem Vorrang.
Klassennamen sind exakt und werden als ganzer Token verglichen, nie als Muster: Der Vergleich läuft im Browser jedes Besuchers, und ein Muster wäre dort ein Risiko auf deiner eigenen Seite. Höchstens 24 Regeln, pro Klassenname [a-z0-9_-] und höchstens 32 Zeichen, jede Klasse nur einmal. Groß- und Kleinschreibung spielt keine Rolle (die Namen werden auf beiden Seiten kleingeschrieben), anders als bei den eingebauten Rulesets.
Gesetzt wird das über die Applikations-API (pagetype_rules bei POST oder PATCH /applications) oder in der Page-Type-Einstellung im Dashboard, die die Klassennamen auch für dich herausfinden kann.
PII: die engste Form des Body-Class-Reads. Mit Regeln und ohne Ruleset kann nur ein Token den Browser verlassen, das du selbst benannt hast. Das volle class-Attribut wird nie gelesen, und es bleibt bei einem Token pro Pageview.
Die Klassennamen deines Themes finden
Zwei Setup-Helfer beantworten die zwei Fragen, die die Einstellung stellt. Beide laufen aus dem Dashboard neben der Einstellung und über die API, beide lesen nur die eigenen Domains der Applikation, und beide sind auf zehn Läufe pro Organisation und Stunde begrenzt. Keiner schreibt etwas: Sie schlagen vor, bestätigt wird durch Speichern.
- Welches Shop-System ist das?
POST /applications/{id}/detect-pagetypeliest die eigene Startseite der Applikation und nennt die passende Ruleset, mit den Belegen dafür und dem Page-Type, den sie für diese Seite erfasst hätte. Shopify und PrestaShop werden erkannt und als nicht wählbar markiert: Shopify meldet seinen Page-Type stattdessen überServer-Timing, PrestaShop hat noch keine Ruleset. Eine Startseite, die mit einer Bot-Challenge antwortet, wird als fehlgeschlagener Probe-Lauf gemeldet und nicht als „Shop-System nicht erkannt". - Welche Klasse heißt „Product"?
POST /applications/{id}/pagetype/discovernimmt bis zu vier deiner Seiten, jede mit der Angabe, was sie ist, liest sie zusammen mit deiner Startseite als Kontrast und schlägt die Klasse vor, die nur diese Art Seite trägt. Zwei Beispiele desselben Typs geben die sicherste Antwort, denn was sich zwischen ihnen unterscheidet, kann nicht das Merkmal sein. Ein Page-Type mit genau einem Kandidaten kommt fertig zum Speichern zurück; mehrere Kandidaten werden aufgelistet und nicht zu einer Regel gemacht, und ein Typ, den das Theme gar nicht markiert, kommt leer zurück statt geraten.
Ingest und Routing
site_policy
Entscheidet, was passiert, wenn ein Beacon von einem Hostnamen kommt, der keine registrierte Site dieser Application ist. open (der Default) verwirft das Beacon, vermerkt den Hostnamen aber als vorgeschlagene Domain, die du mit einem Klick adoptierst; auto legt dafür eine Site an und behält ihren Traffic ab dann; strict verwirft ohne Vorschlag und ohne Auto-Provisioning, sodass nur exakt registrierte Domains bedient werden. Wird an der Application gesetzt.
Das ersetzt die frühere allowed_origins-Allow-List und den per-Site-Schalter enforce_domain_match, die es beide nicht mehr gibt: Abgeglichen wird jetzt der gemeldete Seiten-URL-Host statt des Origin-Headers, den sendBeacon oft weglässt. Mit strict nagelst du den Ingest auf explizit registrierte Domains fest.
PII: keine. Das ist Ingest-Härtung, kein Datenerhebungsschalter.
collector_mode
Wohin das Beacon seine Daten POSTet: default (fastmons geteilter Collector), custom (ein expliziter Endpunkt, den du hostest oder routest, gesetzt in collector_endpoint) oder relative (ein host-loses same-origin /c/<hash>, natürlich, wenn du den Collector von deiner eigenen Domain ausliefern lässt). Default default.
PII: für sich keine. Es ist eine Routing-Wahl. Beachte, dass ein Same-Origin- oder Custom-Endpunkt den Netzwerkpfad des Requests ändert, was für deinen eigenen Consent und die First-Party-Einordnung relevant sein kann, aber es ändert nicht, was das Beacon erhebt.
collector_endpoint
Die absolute Collector-Basis-URL, nur genutzt, wenn collector_mode custom ist (etwa metrics.example.com). Muss für custom gesetzt und sonst leer sein. Default leer.
PII: keine. Nur Endpunkt-Konfiguration.
data_retention_days
Wie lange rohe Beacon-Zeilen gehalten werden, bevor die Speicherschicht sie verwirft: 30, 60, 90, 180 oder 365 Tage. Default 90. Aggregate, die im Fenster berechnet wurden, bleiben; die rohen Zeilen werden bei Ablauf automatisch gelöscht.
PII: das ist dein Hebel zur Speicherbegrenzung. Kürzere Retention ist strenger; wähle das kürzeste Fenster, das dir noch den Vergleich über deine Deploy-Zyklen erlaubt.
Site-Verwaltung
tags
Freie Labels (max. 10) zum Gruppieren verwandter Sites, etwa env:production oder team:growth. Heute nur Labels; ein seitenübergreifender Analytics-Scope, der über jede Site mit einem Tag zusammen berichtet, ist geplant. Siehe Sites → Tags.
PII: keine. Site-Konfiguration, keine Besucherdaten.
is_active
Aus werden Beacons weiterhin angenommen, aber nicht in die Analytics-Tabellen geschrieben, sodass du die Historie der Site behältst, während du neuen Ingest pausierst. Für Pausen nutzen, nicht zum Kürzen der Retention. Default an.
PII: keine. Es gatet Schreibvorgänge, nicht Datenkategorien.
environment
Markiert die Application als prod oder dev. Default prod. Nutze dev, um Staging-, Preview- oder Wegwerf-Applications klar von deinem Produktions-Traffic zu trennen.
PII: keine. Es beschriftet die Application und erhebt nichts.
source_version
Pinnt die Beacon-Template-Version, die die Application ausliefert (v1 ist aktuell). Auf der aktuellen Version lassen, außer du hältst eine Application während eines Beacon-Upgrades bewusst zurück.
PII: keine. Es wählt, welcher Tracker-Build ausgeliefert wird.
Applications und Sites
Diese Einstellungen liegen an der Application, also am Tracking-Embed selbst, nicht an einer einzelnen Domain. Eine Application besitzt das ausgelieferte Bundle, die zwei Hashes und jeden Schalter auf dieser Seite, und sie bedient eine Domain oder zwanzig: Jede Domain ist eine Site mit eigenem Dashboard und eigenem Traffic. Einen separaten „org-weiten Tracker" gibt es nicht mehr; eine Application mit mehreren Sites ist genau das. Siehe Applications.
Eine Site überschreibt keine davon. Braucht eine Domain ein anderes data_retention_days, store_stitch oder count_visitors_by, gehört sie in eine eigene Application.
Einstellungen ändern
Site in fastmon öffnen, auf Einstellungen, ändern, was du brauchst, und speichern. Die Änderung greift, sobald der Script-Cache rolliert: für aktive Besucher meist binnen Minuten, für neue Sessions sofort. Du deployst deine Website nicht neu und änderst das <script>-Tag nicht.
Nächste Schritte
- Applications: der Embed, an dem diese Einstellungen liegen, und wie er zu Sites steht.
- Privacy: Was wir nicht sammeln: die Datenschutz-Untergrenze, die unter jeder Einstellung gilt.
- Der RUM-Beacon: was das Beacon genau schickt.
- Sites: die Domains unter einer Application und typische Setups.