Zum Inhalt springen
thconsulting
Menü öffnen
Tech-Deep-Dive · Analytics

Cookieless. INP-p75.
Multi-Tenant. AI-Search getrennt.

Beacon-Endpoint mit unter 5 kB Tracker-Snippet. Cookieless via SHA-256(ip + ua + dailySalt), INP als p75-Quantil über interactionId-grouped Events, Goal/Journey-State-Machine, eigene AI-Search-Source-Klassifikation (ChatGPT, Perplexity, Claude, Gemini, Copilot getrennt von Organic). Live: analytics.thconsulting.dev.

Capability-Stack

Acht Schichten, was sie können.

Konkrete Tool-Wahl behalte ich für mich, was zählt sind die Eigenschaften: Cookieless ohne Banner, INP-Methodik wie Google, AI-Search als eigene Source-Kategorie.

Identity
Cookieless via täglich rotierender Hash
SHA-256(IP + UA + dailySalt) · 24h-Session-Limit
Performance-Tracking
INP-p75 aus Event-Stream
p75-Quantil pro Pageview · CrUX-konforme Methodik
Source-Klassifikation
Eigene AI-Search-Kategorie
ChatGPT, Perplexity, Claude, Gemini, Copilot getrennt
Goals + Journeys
Glob-Match + Path-Boundary + State-Machine
Soll-vs-Ist-Diff mit Drop-off-Step-Detection
Multi-Tenancy
tenant_id + Domain-Match + Bearer-Token
Service-Layer-Isolation, kein Cross-Tenant-Leak
Browser-Tracker
Eigenes Beacon-Snippet < 5 kB
Native PerformanceObserver, kein Polyfill-Bloat
Deploy
Container-Cluster, Auto-TLS
CI < 2 min · Zero-Downtime via Health-Checks
Reports
CLI mit JSON + Markdown-Output
Cross-Tool-fähig mit site-audit via --analytics-data
Beacon-Schema

Was der Tracker sendet.

Single Endpoint POST /e, serverseitig validiertes Schema, Backend persistiert in events-Table.

// Beacon-Schema (serverseitig validiert)
{
  d: 'thconsulting.dev',          // Domain
  k?: 'site_api_key_for_no_origin', // optional
  t: 'pageview' | 'click' | 'scroll' | 'heartbeat' | 'exit' | 'web-vitals' | 'outbound' | 'download',
  p: '/angebote/build/seo',       // Path
  q?: '?utm_source=...',          // Query
  pv?: 'uuid-v4-pageview-id',     // Pageview-ID für Sub-Event-Aggregation
  r?: 'google.com',               // Referrer-Hostname (gekürzt)
  e?: 'cta-erstgespraech-header', // Event-Name (für click)
  m?: {                           // Meta-Daten je nach Event-Typ
    duration?: 42,                // exit: in Sekunden
    lcp?: 1800,                   // web-vitals: in ms
    cls?: 0.04,
    inp?: 120,                    // p75-Quantil
    inp_max?: 240,                // worst single interaction
    inp_count?: 8,                // Anzahl Interactions
    ttfb?: 320,                   // Navigation Timing
    utm_source?: '...',
    utm_medium?: '...',
    utm_campaign?: '...'
  }
}
FAQ

Tech-Fragen.

Wie ist Cookieless gelöst?
Session-ID = SHA-256(ip + ua + dailySalt). Der dailySalt rotiert täglich um 00:00 UTC via Cron, der alte Salt wird verworfen. Damit ist eine Session über 24 Stunden trackbar, nach Mitternacht aber nicht mehr re-identifizierbar, kein dauerhaftes User-Profiling. DSGVO-konform ohne Banner-Pflicht (TTDSG § 25 Abs. 2 Nr. 2, strictly necessary).
Wie funktioniert INP-p75?
PerformanceObserver mit type:"event", durationThreshold:40 ms. Pro interactionId die längste Duration in Map sammeln. Beim pagehide: durations.sort() plus p75-Quantil berechnen (Math.floor(len * 0.75)). Plus inp_max und inp_count für Debug. Web-Vitals-konform statt nur Worst-Case-Event, gleiche Methodik wie Google CrUX.
Source-Klassifikation Logik?
classifySource() priorisiert. Top-Kategorien: direct, ai-search (ChatGPT/Perplexity/Claude/Gemini/Copilot/You.com/Phind), organic-search (Google/Bing/DuckDuckGo/Ecosia), paid-search (UTM-Mediums cpc/ppc/paid/ads), social, campaign, referral. Hierarchie: utm_source > Referrer > direct. Sticky-First-Touch-Attribution im Report, kein Channel-Hopping bei mehreren Visits.
Wie sind Goals und Journeys modelliert?
goals-Tabelle: matchType (event|path), matchValue mit *-Suffix-Glob ("cta-erstgespraech*" matcht alle CTA-Varianten). Path-Match mit Boundary (/kontakt matcht /kontakt und /kontakt/* aber NICHT /kontaktformular). journeys-Tabelle: expectedSteps als JSON (page/event/scroll/goal/any-of mit exact + optional). analyzeJourneys() macht Soll-vs-Ist-Diff mit Drop-off-Step-Detection, du siehst nicht nur dass jemand abgesprungen ist, sondern auf welchem Schritt.
Multi-Tenant-Pattern?
sites-Tabelle hat tenant_id. Beacon authentifiziert per data-domain Match auf sites.domain. Optional Bearer-Token via data-key für Beacons ohne Origin-Header. site.settings.excludePaths (Glob) plus excludeIps wird respektiert. Pro Site eigener Output-Folder bei Reports, kein Cross-Tenant-Leak möglich. Isolation auf Service-Layer geprüft, nicht nur auf DB-Constraint.
Deploy-Pattern?
Container-Cluster mit Auto-TLS via Reverse-Proxy. CI scheitert früh (Lint, Typecheck, Tests, Build, Container-Push in unter zwei Minuten), Deploy via signiertem Image, Migrations als one-shot-Service vor dem App-Update. Live: analytics.thconsulting.dev, EU-Hosting, Zero-Downtime-Updates via Health-Checks.
Reports laufen wo?
CLI-Tool (bin/report.ts <domain> --days=28). SQL-Aggregation direkt auf der DB (avg_inp/avg_ttfb/cls aus JSONB-Meta extrahiert). Output: analytics-data.json + analytics-report.md + recommendations.md + journeys.md + pages/<slug>.md (analog zum site-audit Pattern). Tool-Kombination via --analytics-data Flag im site-audit für Cross-Tool-Briefs.

Beta-Slot oder Code-Walkthrough?

Beta-Phase 2026 läuft. 30 Min Erstgespräch, kostenlos. Self-Hosting auf eigener DB oder als Build-Add-on.

Erstgespräch buchen