Dokumentation
Anleitungen zum Pflegen von Texten und Regeln, Einrichtung von Timify, Einbindung auf kieu.de und Auswertung im Google Tag Manager.
Grundlagen
Was das Tool ist und wie der Buchungsablauf funktioniert
Überblick
Komponenten, Hosting und Datenquellen
Überblick
Komponenten, Hosting und Datenquellen
Das Kieu Buchungstool ist ein einbettbares Online-Buchungs-Widget mit eigener Oberfläche. Im Hintergrund nutzt es die Timify Booker Services API für Standorte, Leistungen, Verfügbarkeiten und Buchungen.
Produktiv läuft das Widget auf Netlify (z. B.
kieu-buchungstool.netlify.app). Auf kieu.de (Shopify) wird
es per embed.js in einem Modal geöffnet — Nutzer bleiben auf der Website.
| Komponente | Zweck | Pflege |
|---|---|---|
widget.html |
Buchungs-UI (Iframe-Inhalt) | Code-Deploy |
embed.js |
Modal, Tracking-Weiterleitung, UTM-Übergabe | Code-Deploy |
public/*.json |
Texte & Regeln | Ohne Neu-Build auf dem Server |
| Netlify Functions | SMS-OTP über Sinch | Netlify Environment |
Architektur & Buchungsablauf
Schritte im Widget und Datenquellen
Architektur & Buchungsablauf
Schritte im Widget und Datenquellen
| Schritt | Screen | Datenquelle |
|---|---|---|
| 0 | Standort wählen | Timify companies |
| 1 | Behandlung wählen | Timify Services (Karten + Accordions) |
| 1b | Zusatzleistungen (optional) | content.json → addons |
| 2 | Termin wählen | Timify + appointmentSuggestions |
| 3 | Kontaktdaten | Formular → Timify Kundenfelder |
| 4 | SMS-Verifizierung | Sinch OTP (falls aktiv) |
| 5 | Bestätigung | Timify appointments/confirm |
Der Stepper oben zeigt 3 Schritte: Behandlung → Tag & Uhrzeit → Kontaktdaten. Standort, Zusatzleistungen und SMS sind Teil des Flows, aber nicht als eigene Stepper-Nummer sichtbar.
Reservierung kurz erklärt
- Nutzer wählt Termin und füllt Kontaktdaten aus
- Timify reserviert den Slot (~5 Min.) via
POST /reservations - Sinch sendet SMS-Code (wenn OTP aktiv)
- Nach erfolgreicher Prüfung:
POST /appointments/confirm
Texte
Überschriften, Formular-Labels, Buttons und Erfolgstexte — meist ohne Neu-Build änderbar
JSON-Dateien (Übersicht)
Welche Datei wofür — und wo sie liegt
JSON-Dateien (Übersicht)
Welche Datei wofür — und wo sie liegt
Drei Dateien in public/ können nach dem Deploy direkt auf dem Server
ersetzt werden — ohne Neu-Build. Ein Hard-Reload im Browser reicht
meist aus.
| Datei | Inhalt | Wer pflegt das? |
|---|---|---|
ui-strings.json |
Überschriften, Labels, Buttons, Fehlermeldungen | Praxis / Marketing |
content.json |
Zusatzleistungen, Termin-Vorschlags-Regeln | Praxis / Projektteam |
booking-settings.json |
Texte auf der Erfolgsseite | Praxis / Marketing |
So änderst du JSON-Dateien auf dem Live-System
-
Datei lokal bearbeiten (im Repo unter
public/) oder direkt auf Netlify im Deploy-Ordner ersetzen. -
Per Git: Änderung committen und auf
masterpushen — Netlify baut neu, die JSON-Dateien landen indist/. - Alternativ ohne Git: Nur die JSON-Datei im Netlify-Deploy ersetzen (z. B. per Drag & Drop im Netlify-UI, wenn euer Workflow das erlaubt).
-
Im Browser testen:
https://kieu-buchungstool.netlify.app/widget.htmlmit Hard-Reload (Cmd+Shift+R). - JSON-Syntax prüfen: gültige Anführungszeichen, keine trailing commas — sonst lädt das Widget die Fallback-Texte aus dem Code.
Alternative Pfade per URL-Parameter:
?ui=…&content=…&settings=…
Nur per Code-Deploy: neue UI-Keys, Design, Schriftarten, Stepper-Labels in
widgetDefaults.js.
UI-Texte ändern
ui-strings.json — Überschriften, Formular, Buttons
UI-Texte ändern
ui-strings.json — Überschriften, Formular, Buttons
Alle sichtbaren Texte im Widget (Überschriften, Untertitel, Formular-Labels, Buttons,
Fehlermeldungen) werden aus ui-strings.json geladen. Es reicht, nur die Keys
einzutragen, die ihr ändern wollt — fehlende Keys nutzen den Standard aus dem Code.
So änderst du einen UI-Text
-
Öffne
public/ui-strings.jsonim Projekt (oder die Live-Datei unterhttps://kieu-buchungstool.netlify.app/ui-strings.json). - Suche den passenden Key (siehe Tabelle unten) oder trage einen neuen Key mit deinem Wunschtext ein.
- Speichern — JSON muss gültig bleiben (Kommas zwischen Einträgen, keine Kommas am Ende).
- Datei deployen (Git-Push auf
masteroder manuell auf Netlify ersetzen). - Widget im Browser neu laden und den betroffenen Schritt prüfen.
Beispiel
{
"selectLocationTitle": "Wähle deinen Standort",
"selectServiceTitle": "Wähle deine Behandlung",
"contactFormTitle": "Fülle deine Kontaktdaten aus",
"suggestedSlotsTitle": "Für dich vorgeschlagen",
"continueBooking": "Buchung fortsetzen",
"preferredDoctorLabel": "Behandler:in",
"confirmAddToCalendar": "Zum Kalender hinzufügen",
"confirmCalendarApple": "Apple Kalender",
"confirmCalendarGoogle": "Google Kalender",
"confirmCalendarOutlook": "Microsoft Outlook"
}
Wichtige Key-Gruppen
| Gruppe | Beispiel-Keys | Was du änderst |
|---|---|---|
| Schritt-Überschriften | selectLocationTitle, selectDatetimeTitle, contactFormTitle |
Große Titel pro Screen |
| Untertitel | selectLocationSubtitle, contactFormSubtitle |
Erklärtext unter dem Titel |
| Formular | fieldFirstName, fieldEmail, privacyConsent |
Feld-Labels und Checkbox-Texte |
| Termin | suggestedSlotsTitle, noSlots, preferredPeriodNext |
Termin-Auswahl und Filter |
| Buttons | continue, back, skipAddons |
Aktions-Buttons |
| Bestätigung | confirmSuccessTitle, confirmAddToCalendar |
Erfolgsseite (Titel, Kalender-Button) |
Einzelne Keys können auch in booking-settings.json unter
"ui": { … } überschrieben werden — das hat Vorrang vor
ui-strings.json.
Neuer Text-Key, der im Code noch nicht existiert? Dann muss der Key in
src/content/uiStrings.js ergänzt und ein Code-Deploy gemacht werden.
Bestätigungstexte ändern
booking-settings.json — Texte nach erfolgreicher Buchung
Bestätigungstexte ändern
booking-settings.json — Texte nach erfolgreicher Buchung
Nach der Buchung zeigt das Widget einen Erfolgstext. Welcher Text erscheint, steuert ihr
über booking-settings.json — global oder pro Leistung.
So änderst du den Erfolgstext
- Öffne
public/booking-settings.json. -
Unter
confirmVariantsden Text fürvisit(normaler Besuch) oderfollowUp(Rückruf/Kostenklärung) anpassen. -
Optional: Unter
confirm.variantglobal"visit"oder"followUp"setzen — gilt für alle Leistungen. -
Optional: Unter
confirm.serviceVariantspro Timify-Leistungs-ID eine Variante zuweisen (z. B."69f361562c7b933ec4960f7c": "followUp"). - Speichern, deployen, Erfolgsseite im Widget testen (Testbuchung oder Demo-Flow).
Beispiel-Konfiguration
{
"confirm": {
"variant": null,
"serviceVariants": {
"TIMIFY_SERVICE_ID": "followUp"
}
},
"confirmVariants": {
"visit": {
"subtitle": "Vielen Dank für dein Vertrauen. Wir freuen uns auf deinen baldigen Besuch!"
},
"followUp": {
"subtitle": "Bzgl. Leistungsumfang und Kosten werden wir dich in den nächsten Tagen telefonisch kontaktieren."
}
}
}
Leistungs-ID finden
- Timify → Leistung öffnen → ID aus der URL kopieren
- Oder: Externe ID verwenden, wenn in Timify gesetzt
Termine & Buchung
Regeln für Vorschläge, Zusatzleistungen und Behandler-Auswahl
„Für dich vorgeschlagen“ anpassen
content.json → appointmentSuggestions
„Für dich vorgeschlagen“ anpassen
content.json → appointmentSuggestions
Der Bereich wählt automatisch freie Timify-Slots. Ihr legt Regeln fest — keine festen Termine in der JSON-Datei.
So änderst du die Termin-Vorschläge
- Öffne
public/content.json. -
Trage unter
appointmentSuggestionsDefaultsdie Standard-Regeln ein (gilt für alle Leistungen ohne eigene Regel). -
Für eine bestimmte Behandlung: Unter
appointmentSuggestionseinen Eintrag mit der Timify Externen ID oder Service-ID als Key. - Speichern und
content.jsonauf dem Server ersetzen — kein Neu-Build nötig. - Im Widget die Behandlung wählen und prüfen, ob Anzahl, Abstand und Uhrzeiten passen.
| Feld | Bedeutung | Standard |
|---|---|---|
defaultPeriod |
Start-Wunschzeitraum: next, 2w, 3w, 4w |
next |
dayCount |
Anzahl vorgeschlagener Tage (1–5) | 2 |
timesPerDay |
Uhrzeiten pro Tag (1–6) | 2 |
minDayGap |
Mindestabstand zwischen Vorschlags-Tagen | 3 |
preferTimes |
Bevorzugte Uhrzeiten, z. B. ["09:00","10:00"] |
— |
{
"appointmentSuggestionsDefaults": {
"defaultPeriod": "next",
"dayCount": 2,
"timesPerDay": 2,
"minDayGap": 3
},
"appointmentSuggestions": {
"ERSTBERATUNG": {
"defaultPeriod": "2w",
"minDayGap": 7,
"preferTimes": ["09:00", "10:00"]
}
}
}
Upselling & Zusatzleistungen
Ablauf, Konfiguration und Texte
Upselling & Zusatzleistungen
Ablauf, Konfiguration und Texte
Ablauf im Widget
Nach der Auswahl einer Hauptbehandlung prüft das Widget, ob Zusatzleistungen (Upsells) hinterlegt sind. Nur dann erscheint der Screen „Zusatzleistung buchen?“ — er ist nicht als eigener Schritt im Stepper sichtbar (intern Schritt 1b).
Wann erscheint der Upsell-Screen?
| Situation | Verhalten |
|---|---|
Hauptleistung hat Einträge unter addons (oder Timify-Upsell-Daten) |
Upsell-Screen mit angebotenen Zusatzleistungen |
| Keine Verknüpfung / leeres Array | Kein Upsell-Screen — direkt zur Terminauswahl |
| Nutzer klickt „Weiter ohne Zusatzleistung“ | Upsell übersprungen, Terminbuchung wie gewohnt |
| Nutzer wählt eine Zusatzleistung | Zusatz erscheint in der Buchungsübersicht (Name + Preis) |
Was kommt woher?
| Daten | Quelle | Pflege |
|---|---|---|
| Name, Preis, Dauer der Zusatzleistung | Timify API (GET /companies) |
In Timify |
| Welche Hauptleistung → welche Zusätze? | content.json → addons (Standard) |
JSON auf dem Server |
| Upsell-Kombinationen aus Timify Upselling App | Timify API (optional, siehe addonsConfig) |
Timify Marketplace App |
| Texte auf dem Upsell-Screen | ui-strings.json |
JSON auf dem Server |
Wichtig: In content.json tragt ihr nur die Verknüpfung
(IDs) ein — keine Texte oder Preise. Empfehlung: in Timify bei allen Leistungen eine
Externe ID setzen (z. B. BOTOX-HAUPT), damit die JSON-Einträge
lesbar und stabil bleiben.
addonsConfig — Datenquelle wählen
Steuert, woher das Widget die Upsell-Zuordnung liest:
{
"addonsConfig": {
"source": "content",
"fallbackToContent": false
},
"addons": { … }
}
| Einstellung | Wert | Bedeutung |
|---|---|---|
source |
"content" (Standard) |
Upsells nur aus addons in content.json |
source |
"timify" |
Zuerst Upsell-Felder aus der Timify-companies-Response (Upselling App) |
fallbackToContent |
true |
Bei source: "timify": wenn Timify keine Upsells liefert, auf addons zurückfallen |
So richtest du Upselling ein (content.json)
- In Timify: Haupt- und Zusatzleistung als Einzelleistung, online buchbar, jeweils Externe ID vergeben.
- Öffne
public/content.json. -
Unter
addons: Schlüssel = Externe ID (oder Service-ID) der Haupt-Leistung, Wert = Array der Zusatz-IDs. - Speichern, auf dem Server deployen — kein Neu-Build nötig.
- Im Widget die Hauptbehandlung wählen und prüfen: Upsell-Screen oder direkt Termin.
Beispiel addons
{
"addonsConfig": { "source": "content" },
"addons": {
"BOTOX-HAUPT": ["BLUTANALYSE-ZUSATZ"],
"ERSTBERATUNG": [
"AUFKLAERUNGSBOGEN",
{ "externalId": "DNA-TEST", "sameSlot": true, "hint": "Optional vor dem Termin" }
],
"69f361562c7b933ec4960f7c": [
{ "serviceId": "andere_timify_id", "sameSlot": false }
]
}
}
Felder pro Zusatz-Eintrag
| Feld | Beschreibung |
|---|---|
Kurzer String (z. B. "DNA-TEST") |
Externe ID der Zusatzleistung; sameSlot: true wird angenommen |
externalId / serviceId |
Zusatzleistung in Timify referenzieren |
sameSlot |
true (Standard): Hinweis „Gemeinsam in einem Zeit-Slot buchbar“.
false: kein Slot-Hinweis (z. B. separate Dauer)
|
hint |
Optionaler eigener Text unter der Zusatzleistung (statt Auto-Text aus Preis/Dauer) |
UI-Texte anpassen (ui-strings.json)
| Key | Standard (Auszug) | Wo sichtbar |
|---|---|---|
selectAddonSubtitle |
„Möchtest du eine Zusatzleistung buchen?“ | Untertitel Upsell-Screen |
addonTitlePrefix / addonTitleSuffix |
„Häufig zusammen mit einem … gebucht“ | Titel (Hauptbehandlung wird eingefügt) |
skipAddons |
„Weiter ohne Zusatzleistung“ | Button zum Überspringen |
addonSameSlot |
„Gemeinsam in einem Zeit-Slot buchbar“ | Meta-Hinweis bei sameSlot: true |
addonDurationLabel |
„Dauer“ | Prefix vor der Dauer (falls angezeigt) |
IDs finden
| ID-Typ | In Timify | Im JSON |
|---|---|---|
| Externe ID | Leistung bearbeiten → Feld „Externe ID“ | Als Schlüssel unter addons oder als String im Array |
| Service-ID | Leistung öffnen → ID aus der URL, oder Konsole: services[].id |
Alternative zur Externen ID (intern, kann sich ändern) |
Fehlersuche
- Upsell-Screen fehlt trotz JSON: Hauptleistungs-ID stimmt nicht (Externe ID vs. Service-ID prüfen).
- Screen leer / keine Karten: Zusatz-IDs in Timify nicht gefunden oder Leistung nicht online buchbar.
-
Browser-Konsole (F12): Warnung
addons: … konnte nicht aufgelöst werden→ falsche ID im Array. -
Mit
VITE_DEBUG_CONSOLE=trueim Build: zusätzliche Logs zu Timify-Upsell-Feldern.
Technischer Hinweis: Die Timify Reservation-API nimmt pro Buchung aktuell
eine service_id (die Hauptbehandlung). Zusatzleistungen sind in der
UI und Zusammenfassung sichtbar; ob Timify sie als kombinierte Buchung speichert, bitte mit der
Praxis in Timify klären.
Behandler (gezielte Auswahl)
Reihenfolge, Sichtbarkeit und Label ändern
Behandler (gezielte Auswahl)
Reihenfolge, Sichtbarkeit und Label ändern
Behandler werden aus Timify geladen (Ressourcen-Kategorie „Ärzteteam“ bzw.
Name enthält „Arzt“). Es gibt aktuell keine JSON-Liste im Buchungstool.
Die gezielte Behandlerauswahl ist nur verfügbar, wenn Timify für die Leistung
Ärzte in availabilities.resources liefert. Maßgeblich für die tatsächliche Zuweisung
ist immer Timify (Confirm-Response).
So änderst du die Behandler-Auswahl
-
Reihenfolge: In Timify beim Behandler den
orderIndexsetzen — niedrigere Werte erscheinen weiter oben. - Ausblenden: Leistung dem Behandler nicht zuweisen, Ressource deaktivieren oder keine Verfügbarkeiten hinterlegen.
-
Label im UI: In
ui-strings.jsondie KeyspreferredDoctorLabelundselectPreferredDoctoranpassen. - Das Dropdown erscheint nur bei Leistungen mit gezielter Behandlerauswahl (Timify liefert passende Ressourcen) — bei Pool-Leistungen wie Check-up wird es ausgeblendet.
Technik & Betrieb
Timify-Anbindung, SMS-Verifizierung und Deploy
Timify einrichten
Enterprise, Leistungen, Kundenfelder
Timify einrichten
Enterprise, Leistungen, Kundenfelder
Kieu nutzt Timify Enterprise (Branch Manager): eine Enterprise-ID,
mehrere Filialen. Das Widget lädt alle Standorte und nutzt danach die
company_id der gewählten Filiale.
So richtest du Timify ein
- Enterprise-ID aus Timify kopieren und in Netlify als
VITE_TIMIFY_ENTERPRISE_IDsetzen. - Leistungen in Timify pflegen — jeweils Externe ID vergeben (wichtig für
content.json). - Kundenfelder für Online-Buchung aktivieren (Vorname, Nachname, E-Mail, Telefon).
- Behandler als Ressourcen in Kategorie „Ärzteteam“ anlegen.
- Neu-Deploy auf Netlify auslösen, damit die Environment-Variablen im Build landen.
Build-Umgebung (.env / Netlify)
VITE_TIMIFY_ENTERPRISE_ID=deine-enterprise-id
VITE_TIMIFY_LOCALE=de-de
VITE_BASE_PATH=/
VITE_OTP_ENABLED=true
SINCH_APPLICATION_KEY=…
SINCH_APPLICATION_SECRET=…
| Variable | Bedeutung |
|---|---|
VITE_TIMIFY_ENTERPRISE_ID |
Enterprise-ID — alle Filialen unter einem Tool |
VITE_TIMIFY_ACCOUNT_ID |
Alternative: nur eine Filiale (ohne Standortliste) |
VITE_BASE_PATH |
Deploy-Pfad auf Netlify — Produktion Kieu: / (Root). Unterordner nur für Staging, z. B. /kieu-buchungstool/ |
VITE_OTP_ENABLED |
true / false — SMS-Schritt ein/aus |
Standort-Namen, Adressen und Leistungspreise kommen aus Timify — nicht aus den JSON-Dateien.
SMS-Verifizierung (OTP)
Sinch über Netlify Functions
SMS-Verifizierung (OTP)
Sinch über Netlify Functions
OTP läuft über Sinch Verification API — nicht über Timify SMS. Die Endpunkte
/api/otp/send und /api/otp/verify sind Netlify Functions.
So schaltest du OTP ein oder aus
- In Netlify:
SINCH_APPLICATION_KEYundSINCH_APPLICATION_SECRETsetzen. VITE_OTP_ENABLED=truefür aktiven SMS-Schritt (erfordert Neu-Build).- Zum Testen ohne SMS:
VITE_OTP_ENABLED=falsesetzen und neu deployen. -
Nur
dist/per FTP hochladen reicht nicht — es braucht den vollen Netlify-Deploy inkl. Functions.
Deploy & Netlify
Live schalten und Dateien aktualisieren
Deploy & Netlify
Live schalten und Dateien aktualisieren
So bringst du Änderungen live
-
Code-Änderungen: Committen, auf
masterpushen — Netlify baut automatisch (npm run build, Publish:dist). -
Nur Texte/Regeln: JSON-Dateien in
public/ändern und deployen — kein Neu-Build der App-Logik nötig, wenn nur JSON-Inhalt geändert wurde. -
Environment-Variablen in Netlify prüfen (Timify, Sinch,
VITE_BASE_PATH). -
Test-URL:
https://kieu-buchungstool.netlify.app/widget.html
Manuell vom Rechner
npm run netlify:login
npm run netlify:init
npm run netlify:env
npm run netlify:deploy
JSON-Dateien ohne Neu-Build
public/ui-strings.jsonpublic/content.jsonpublic/booking-settings.json
E2E-Monitoring
Automatische Buchungsprüfung via GitHub Actions
E2E-Monitoring
Playwright-Skript prüft den Buchungsflow automatisch
E2E-Monitoring
Playwright-Skript prüft den Buchungsflow automatisch
Das Monitoring führt regelmäßig eine vollständige Testbuchung durch und storniert den Termin danach automatisch. Bei Fehler wird eine Alert-E-Mail versendet. Das Skript läuft als GitHub Actions Workflow — kein eigener Server nötig.
Ablauf des Monitoring-Tests
- Widget öffnen (
widget.html) - Standort und Leistung wählen
- Termin ≥ 2 Tage in der Zukunft auswählen
- Kontaktformular mit Test-Nutzer ausfüllen
- OTP-Schritt: Monitoring-Code wird vom Backend zurückgegeben (kein echter SMS-Versand)
- Buchungsbestätigung prüfen
- Termin automatisch auf
timify.comstornieren - Bei Fehler: erneuter Versuch nach konfigurierter Pause → nach allen Versuchen Alert-E-Mail
OTP-Bypass (Monitoring-Modus)
Das Widget versendet OTP-Codes über Sinch. Im Monitoring-Modus wird Sinch nicht aufgerufen — stattdessen gibt das Netlify-Backend bei Erkennung des geheimen Headers einen festen Code zurück. Echte Buchungen von Nutzern sind davon nicht betroffen.
Einmalig einrichten
-
In Netlify unter Environment variables hinzufügen:
MONITORING_SECRET= zufälliger langer String
(generieren mit:openssl rand -hex 32) - Denselben Wert in
monitoring/config.jsuntermonitoring.secreteintragen - Netlify deployen (damit der neue Env-Var aktiv wird)
- In GitHub unter Settings → Secrets and variables → Actions folgende Secrets anlegen:
| GitHub Secret | Inhalt |
|---|---|
MONITORING_SECRET | Gleicher Wert wie MONITORING_SECRET in Netlify |
TIMIFY_ACCOUNT_ID | Timify Account-ID für den Stornierungslink |
SMTP_HOST | SMTP-Host für Alert-E-Mails |
SMTP_PORT | SMTP-Port (Standard: 587) |
SMTP_USER | SMTP-Benutzername |
SMTP_PASS | SMTP-Passwort |
EMAIL_FROM | Absender-Adresse, z. B. "Kieu Monitoring" <monitor@example.de> |
EMAIL_TO | Empfänger der Alert-E-Mail |
USER_EMAIL | E-Mail-Adresse des Test-Nutzers (für Stornierung) |
GitHub Actions Workflow
Der Workflow liegt unter .github/workflows/monitoring.yml und wird stündlich ausgeführt.
Er kann auch manuell über Actions → Run workflow gestartet werden.
# Datei: .github/workflows/monitoring.yml (liegt im Repo)
# Läuft täglich um 09:00 und 18:00 Berliner Zeit (Sommerzeit).
# Kann auch manuell unter Actions → Run workflow gestartet werden.
# Wichtig: Playwright-Browser werden in jedem Lauf neu installiert
# (npx playwright install chromium --with-deps).
# Das ist nötig, weil node_modules/ im .gitignore ist und
# Playwright-Binaries nicht im Repo liegen.
Lokales Testen
cd monitoring/
npm install
npx playwright install chromium
cp config.example.js config.js
# config.js ausfüllen
npm run check:visible # sichtbarer Browser
npm run check # headless
Fehlersuche
| Problem | Lösung |
|---|---|
| OTP-Code wird abgelehnt | MONITORING_SECRET in Netlify und config.js müssen übereinstimmen — Netlify neu deployen |
| Kein Slot gefunden | Widget lädt Slots asynchron — config.app.timeout erhöhen |
| Zu viele / zu wenige Wiederholungen | monitoring.maxAttempts und monitoring.retryDelayMs in config.js anpassen |
| Stornierung fehlgeschlagen | Stornierungsurl wird im Log ausgegeben — manuell öffnen und stornieren |
| Alert-E-Mail kommt nicht an | SMTP-Zugangsdaten in config.js prüfen — lokal mit SKIP_EMAIL=false npm run check testen |
failure_evidence.png |
Screenshot vom Browser-Stand beim Fehler — als Artifact in GitHub Actions herunterladbar |
Website & Auswertung
Einbindung auf kieu.de und Tracking im GTM
Einbindung auf kieu.de
Empfohlen: embed.js auf Shopify
Einbindung auf kieu.de
Empfohlen: embed.js auf Shopify
So bindest du das Widget auf der Website ein
-
Im Shopify-Theme (oder auf der Zielseite) einen Button mit
data-kieu-booking-openplatzieren. -
embed.jseinmalig einbinden — mitdata-widget-urlunddata-enterprise-id. - GTM/GA4 auf kieu.de lassen — nicht auf Netlify installieren.
- Seite speichern, Button klicken, Modal und Buchungsflow testen.
<button type="button" data-kieu-booking-open>Termin buchen</button>
<script
src="https://kieu-buchungstool.netlify.app/embed.js"
data-widget-url="https://kieu-buchungstool.netlify.app/widget.html"
data-enterprise-id="DEINE_ENTERPRISE_ID"
data-button-label="Termin buchen"
></script>
embed.jsleitet Tracking-Events perpostMessagean die Elternseite weiter- UTM-Parameter der Elternseiten-URL werden ans Widget übergeben
- Mehrere Buttons: alle mit
data-kieu-booking-open, ein Script reicht
Tracking (GTM & GA4)
Buchungs-Funnel auf kieu.de auswerten
Tracking (GTM & GA4)
Buchungs-Funnel auf kieu.de auswerten
Container auf kieu.de: GTM-MJFXB3VX. Das Widget feuert Custom Events in den
dataLayer; embed.js leitet sie an die Elternseite weiter.
So prüfst und nutzt du das Tracking
- GTM Preview auf kieu.de starten und das Buchungs-Modal öffnen.
- Events wie
kieu_booking_step_viewundkieu_booking_completebeobachten. - In GA4:
kieu_booking_completeals Key Event (Conversion) markieren. - Funnel-Auswertung unter GA4 → Explorations anlegen.
| Event | Wann |
|---|---|
kieu_booking_start | Buchung gestartet |
kieu_booking_step_view | Schritt angezeigt |
kieu_booking_step_transition | Wechsel zwischen Schritten |
kieu_booking_action | Klicks (Standort, Termin, Formular, …) |
kieu_booking_abandon | Abbruch vor Abschluss |
kieu_booking_complete | Buchung erfolgreich |
kieu_booking_error | Fehler |
Debug in der Browser-Konsole auf kieu.de:
dataLayer.filter((e) => String(e.event || '').startsWith('kieu_'))
Ausführliche GTM-Anleitung im Repo:
docs/gtm-setup-dr-kieu.md und Import-Datei
docs/gtm-kieu-booking-funnel-import.json.