From ba0f37a5b2aa3ddb60022583b3b03d517d25a215 Mon Sep 17 00:00:00 2001 From: Martin Porwoll Date: Thu, 18 Dec 2025 16:03:45 +0000 Subject: [PATCH] docs(analytics): update URLs to use production endpoints MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update Umami URLs from internal IPs to production (analytics.c2sgmbh.de) - Add Development vs Production URL comparison table - Update UmamiScript component to use production URL as default - Add Payload CMS API URLs to frontend .env.local example - Update server-side tracking to use production Umami - Add global type declarations for gtag and CookieConsent πŸ€– Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- docs/anleitungen/Analytics.md | 981 ++++++++++++++++++++++++++++++++++ 1 file changed, 981 insertions(+) create mode 100644 docs/anleitungen/Analytics.md diff --git a/docs/anleitungen/Analytics.md b/docs/anleitungen/Analytics.md new file mode 100644 index 0000000..fc6b9aa --- /dev/null +++ b/docs/anleitungen/Analytics.md @@ -0,0 +1,981 @@ +# ANALYTICS-LΓ–SUNG: ImplementierungsΓΌbersicht fΓΌr Payload CMS + +*Letzte Aktualisierung: 18. Dezember 2025* + +## Kontext + +Du entwickelst das Multi-Tenant Payload CMS Backend und Next.js Frontend fΓΌr 4 Websites. Diese Dokumentation beschreibt die Analytics-LΓΆsung, die in das Frontend integriert werden muss. + +**Wichtig:** Frontends verwenden die **Production-API** (cms.c2sgmbh.de) und **Production-Analytics** (analytics.c2sgmbh.de). + +--- + +## Architektur-Übersicht + +``` +β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” +β”‚ ANALYTICS ARCHITEKTUR β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ OHNE CONSENT (immer aktiv) β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ UMAMI ANALYTICS β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Server: sv-analytics (10.10.181.103:3000) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Dashboard: http://10.10.181.103:3000 β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Script: /custom.js (Anti-Adblock) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Endpoint: /api/send β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Features: β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Cookieless Tracking (DSGVO-konform ohne Einwilligung) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Pageviews, Sessions, Referrer, UTM-Parameter β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Custom Events (Newsletter, Formulare, CTAs, Downloads) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ 100% Erfassung aller Besucher β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ +β”‚ β”‚ MIT CONSENT (Kategorie: "marketing") β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ GOOGLE ADS CONVERSION β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Client-Side (bei Consent): β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Google Ads Tag (gtag.js) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Conversion Tracking β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Remarketing Audiences β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Server-Side (immer, anonymisiert): β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Google Ads Conversion API β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ Enhanced Conversions (gehashte E-Mail) β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ GCLID-basierte Attribution β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ +β”‚ β”‚ β”‚ GOOGLE CONSENT MODE v2 β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Integration mit bestehendem Orestbida Consent-Banner β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ Kategorie "marketing" steuert: β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ ad_storage β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ ad_user_data β”‚ β”‚ β”‚ +β”‚ β”‚ β”‚ β€’ ad_personalization β”‚ β”‚ β”‚ +β”‚ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ +β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ +β”‚ β”‚ +β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ +``` + +--- + +## Infrastruktur + +### Umami Server + +| Umgebung | Server | URL | Dashboard | +|----------|--------|-----|-----------| +| **Production** | Hetzner 3 | https://analytics.c2sgmbh.de | https://analytics.c2sgmbh.de | +| **Development** | sv-analytics (LXC 703) | https://umami.porwoll.tech | https://umami.porwoll.tech | + +| Eigenschaft | Production | Development | +|-------------|------------|-------------| +| **Tracking Script** | https://analytics.c2sgmbh.de/script.js | https://umami.porwoll.tech/script.js | +| **API Endpoint** | https://analytics.c2sgmbh.de/api/send | https://umami.porwoll.tech/api/send | +| **Datenbank** | umami_db auf Hetzner 3 | umami_db auf sv-postgres | + +### Website-IDs (Multi-Tenant) + +Die Website-IDs werden in Umami fΓΌr jeden Tenant erstellt: + +```typescript +// src/config/analytics.ts + +export const UMAMI_WEBSITE_IDS: Record = { + 'porwoll.de': 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', + 'complexcaresolutions.de': 'yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy', + 'gunshin.de': 'zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz', + 'zweitmeinu.ng': 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', +} + +// Production URL fΓΌr Frontends +export const UMAMI_HOST = process.env.NEXT_PUBLIC_UMAMI_HOST || 'https://analytics.c2sgmbh.de' +``` + +--- + +## Frontend-Integration + +### 1. Umami Script Komponente + +```typescript +// src/components/analytics/UmamiScript.tsx + +'use client' + +import Script from 'next/script' + +interface UmamiScriptProps { + websiteId: string + host?: string +} + +export function UmamiScript({ + websiteId, + host = 'https://analytics.c2sgmbh.de' // Production default +}: UmamiScriptProps) { + if (!websiteId) return null + + return ( +