Live testen (empfohlen): kopiere die Datei in dein Produktions‑Dokument‑Root so, dass sie unter `https://yourdomain/scripts/sw.js` erreichbar ist. In diesem Repo habe ich die Datei zusätzlich ins Projekt‑Root (`/sw.js`) und in [docroot/sw.js](docroot/sw.js) gelegt. Live testen (empfohlen): kopiere die Datei in dein Produktions‑Dokument‑Root so, dass sie unter `https://yourdomain/sw.js` erreichbar ist (Root Pfad). In diesem Repo habe ich die Datei zusätzlich ins Projekt‑Root (`/sw.js`) und in [docroot/sw.js](docroot/sw.js) gelegt. Kurz: Anleitung zur Aktivierung des Header‑Ads (Propeller / AdSense) 1) Umgebungsvariablen - Lege in deiner lokalen Umgebung (z. B. `.env.local`) folgende Variablen an: - `VITE_AD_PROVIDER=propeller` # oder `adsense` - `VITE_PROP_SCRIPT_URL=https://example-propeller.example/ads.js` # Propeller: Script/Endpoint - `VITE_PROP_SLOT=YOUR_PROP_SLOT_ID` - `VITE_ADSENSE_CLIENT=ca-pub-XXXXXXXXXXXX` # nur bei AdSense - `VITE_ADSENSE_HEADER_SLOT=NNNNNNNNNN` # nur bei AdSense - `VITE_HEADER_STICKY=true` # `true`=thin sticky header, `false`=static 2) Was ich bereits implementiert habe - `client/src/components/HeaderAdBanner.vue` wurde erweitert: unterstützt `propeller` + `adsense`, lazy load nach Interaktion, prüft `localStorage('ads_consent')`, und kann sticky sein. - `HeaderAdBanner` wurde in die Chat‑Ansicht eingebaut: [client/src/views/ChatView.vue](client/src/views/ChatView.vue) 3) Consent‑Handling (was du tun musst) - Der Code wartet auf einen Consent-Wert in `localStorage` unter dem Key `ads_consent` (Wert `'true'`). - Du solltest eine Consent‑UI (CMP / IAB TCF) implementieren, die nach Zustimmung `localStorage.setItem('ads_consent','true')` setzt und das Event `window.dispatchEvent(new Event('ads:consent-granted'))` feuert. - Kurztest (ohne CMP): Öffne die Konsole und führe aus: ```js localStorage.setItem('ads_consent','true'); window.dispatchEvent(new Event('ads:consent-granted')); ``` 4) Propeller‑Integration - Propeller liefert normalerweise ein Provider‑Snippet. Trage die korrekte `VITE_PROP_SCRIPT_URL` und `VITE_PROP_SLOT` ein. - Falls Propeller ein Inline‑Div erwartet, liefere mir das Snippet/Anweisungen und ich passe `HeaderAdBanner.vue` an (derzeit wird ein iframe mit `?slot=` angehängt als generischer Fallback). 5) Test & Dev - Dev starten: ```bash cd client npm install npm run dev ``` - Besuche eine Chat‑Konversation (eingeloggt) und prüfe, ob das Header‑Ad nach Interaktion oder Consent geladen wird. 6) A/B‑Test‑Vorschlag (kurz) - Variante A: statischer Header (VITE_HEADER_STICKY=false) - Variante B: thin sticky header (VITE_HEADER_STICKY=true) - Metriken: RPM, CTR, Session Length, Bounce Rate. Testlauf: 2 Wochen oder mind. 10k Seitenaufrufe pro Variante. Hinweis: Die Anwendung weist jedem neuen Besucher automatisch eine Variante zu (localStorage `ads_ab_variant` = `A` oder `B`). Kurzbefehle zum Debugging: - Aktuelle Variante anzeigen: ```js localStorage.getItem('ads_ab_variant') ``` - Variante zurücksetzen (erneute Zuteilung bei Neuaufruf): ```js localStorage.removeItem('ads_ab_variant'); location.reload(); ``` Events: - `ads:ab-assigned` → Fired when a user is assigned to A or B. Detail: `{variant:'A'|'B'}`. - `ads:load-start` and `ads:loaded` → Fired around ad load with `{provider, variant}`. 7) Monitoring & Events (optional) - Um schnelle Messungen zu erhalten, feuere ein Custom Event beim Ad‑Load: ```js window.dispatchEvent(new CustomEvent('ads:loaded',{detail:{provider: 'propeller'}})) ``` - Du kannst im Frontend listeners registrieren und diese Events an dein Analytics (Matomo/GA4) weiterleiten. Wenn du mir jetzt die echte `VITE_PROP_SCRIPT_URL` und `VITE_PROP_SLOT` gibst, baue ich das Inline‑Snippet exakt so ein, wie Propeller es erwartet. Möchtest du, dass ich auch eine minimale Consent‑UI direkt in `client` ergänze (ein einfacher Banner mit Zustimmen/ablehnen)?