HTML-Seitenstruktur
Minimale Seitenstruktur mit Header, optionaler Sidebar und einem Widget im Hauptbereich.
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Meine Buchungsseite</title>
<script src="https://cdn.anny.co/widget/annyComponents.umd.latest.min.js"></script>
</head>
<body>
<header>
<a href="/">Dein Logo</a>
<nav><!-- Navigation --></nav>
<a-login-button base-url="https://anny.co"></a-login-button>
<a-cart-modal-button base-url="https://anny.co" modal-layout="drawer"></a-cart-modal-button>
</header>
<main>
<aside><!-- optionale Sidebar --></aside>
<div>
<a-resource-booking-panel
base-url="https://anny.co"
resource="my-resource"
></a-resource-booking-panel>
<!-- weiterer Seiteninhalt -->
</div>
</main>
</body>
</html>
Das Script wird einmal im
<head>geladen.a-login-buttonunda-cart-modal-buttongehören in den Header, damit sie auf allen Seiten sichtbar bleiben.Ersetze das Panel durch ein Seiten-Widget mit
fullscreen="true"undnav-height, wenn die Buchung die gesamte Viewport-Höhe füllen soll (siehe Ganzseitige Widgets weiter unten).
Ganzseitige Widgets
Seiten-Widgets eignen sich, wenn das Widget den Hauptinhalt der Seite darstellt.
Seiten-Widgets:
a-organization-pagea-organization-mapa-organization-calendara-resource-pagea-resource-mapa-resource-calendara-service-pagea-subscription-pagea-package-pagea-my-bookings
Empfohlene Integration für ganzseitige Layouts
Verwende fullscreen="true", damit das Widget die verfügbare Viewport-Höhe ausfüllt. Wenn deine Website einen festen Header hat, übergib zusätzlich nav-height, damit das Widget nicht darunter gerendert wird.
<a-resource-calendar
base-url="https://anny.co"
resource="my-resource"
fullscreen="true"
nav-height="72px"
></a-resource-calendar>
Hinweise:
fullscreen="true"entsprichtheight: 100vh.nav-heightändert das aufcalc(100vh - nav-height).Wenn du
heightsetzt, wird die automatische Größenanpassung deaktiviert und der iframe hat eine feste Höhe.Für
*-page, Map-, Kalender- unda-my-bookings-Widgets sind ganzseitige Layouts in der Regel die sauberste Integration.
Organization-Map und Organization-Kalender
Diese sind Seiten-Widgets, keine Modal-Buttons. Behandle sie wie einen vollständigen Seitenbereich.
<a-organization-map
base-url="https://anny.co"
organization="my-org"
fullscreen="true"
></a-organization-map>
<a-organization-calendar
base-url="https://anny.co"
organization="my-org"
calendar-view="week"
fullscreen="true"
></a-organization-calendar>
Verwende die Organization-Map, wenn die Karte die primäre Benutzeroberfläche ist. Verwende den Organization-Kalender, wenn die Verfügbarkeitsnavigation im Vordergrund steht. Wenn du stattdessen den vollständigen Explore-Flow möchtest, nimm a-organization-page.
Panels
Booking-Panels sind bewusst kompakt gehalten und sperren die Navigation.
Panel-Widgets:
a-resource-booking-panela-service-booking-panel
Wichtiges Verhalten:
Panels verwenden immer dynamische Höhe.
Externe
height- undfullscreen-Werte werden ignoriert.Panels sind dazu gedacht, den Buchungsfluss in dein eigenes Seitenlayout einzubetten.
<a-service-booking-panel
base-url="https://anny.co"
service="intro-call"
></a-service-booking-panel>
Login-Button und Warenkorb-Button
Diese zwei Komponenten werden unter Organisation → Einstellungen → Buchungsseite → Globale Komponenten konfiguriert. Sie sind als gemeinsame Steuerelemente gedacht, die sich in der Regel im Site-Header oder in einer fixen Navigationsleiste befinden.
Login-Button
Verwende a-login-button, wenn du ein gemeinsames Login/Logout-Element benötigst, das mit der Widget-Session synchron bleibt.
<a-login-button
base-url="https://anny.co"
locale="de"
idp-uuid="your-idp-uuid"
></a-login-button>
Verhalten:
Lädt einen eigenen Login-iframe.
Wechselt automatisch in den eingeloggten Avatar-Zustand.
Sendet Auth-Änderungen weiter, damit benachbarte Widgets ihren Authentifizierungszustand aktualisieren.
Gute Platzierungen:
Haupt-Site-Header
Mobile Navigation Drawer
Obere Leiste auf Buchungs-Landingpages
Warenkorb-Button
Verwende a-cart-modal-button, wenn Nutzer Artikel aus Booking-Widgets hinzufügen und später auschecken sollen.
<a-cart-modal-button
base-url="https://anny.co"
modal-layout="drawer"
label="Warenkorb"
></a-cart-modal-button>
Verhalten:
Zeigt eine Live-Badge mit der Artikelanzahl.
Bleibt mit benachbarten Widgets auf derselben Seite synchron.
Öffnet den Checkout in einem Modal-Overlay.
Häufige Kombinationen:
a-resource-booking-panelzusammen mita-cart-modal-buttonMehrere Booking-Widgets auf einer Seite mit einem gemeinsamen Warenkorb-Button
Events und Tracking
Die meisten Embed-Widgets leiten Buchungs-Lifecycle-Events als DOM Custom Events weiter. Trifft für alles aus den Login-Button zu.
Unterstützte Event-Namen:
view-pageadd-to-cartstart-checkoutcomplete-checkout
Häufige Felder im Event-Payload:
event_namevaluegross_valuetaxcurrencytransaction_iditems
Beispiel:
<a-resource-page
id="booking-widget"
base-url="https://anny.co"
resource="my-resource"
></a-resource-page>
<script>
const widget = document.getElementById('booking-widget')
widget.addEventListener('complete-checkout', (event) => {
const data = event.detail
console.log('Checkout abgeschlossen', data.transaction_id, data.gross_value, data.currency)
})
</script>
GA4-Beispiel:
<script>
const widget = document.getElementById('booking-widget')
widget.addEventListener('complete-checkout', (event) => {
const data = event.detail
gtag('event', 'purchase', {
currency: data.currency,
value: data.gross_value ?? data.value,
transaction_id: data.transaction_id,
items: (data.items || []).map((item) => ({
item_id: item.id,
item_name: item.name,
quantity: item.quantity,
price: item.price,
})),
})
})
</script>
Hinweise:
a-login-buttonunda-cart-modal-buttonsind Hilfs-Widgets und senden keine Buchungs-Events.Seiten-Widgets, Maps, Kalender, Booking-Panels und checkout-orientierte Seiten senden Buchungs-Events.
Subscription- und Package-Widgets senden checkout-fokussierte Events. In der Praxis sind
view-page,start-checkoutundcomplete-checkoutdie relevantesten.
UTM-Parameter und Click-IDs
Für Attribution musst du nichts weiter tun. Wenn ein Widget lädt, liest es den Query-String der übergeordneten Seiten-URL aus und leitet diese Parameter automatisch in den eingebetteten iframe weiter:
Parameter | Plattform |
| Alle (Google Analytics u. a.) |
| Google Ads |
| Meta / Facebook Ads |
| TikTok Ads |
| LinkedIn Ads |
Wenn ein Nutzer also über ?utm_campaign=fruehling&gclid=abc123 auf deine Seite kommt, trägt das Widget diese Werte durch den gesamten Buchungsfluss – Conversion-Tracking funktioniert ohne zusätzliche Konfiguration.
Es ist kein HTML-Attribut erforderlich – die Weiterleitung erfolgt automatisch bei jedem Widget-Ladevorgang.
Start- und Enddatum
Die meisten Widgets akzeptieren start (und manchmal end), um Kalender oder Karte auf einen bestimmten Datumsbereich vorzunavigieren.
ISO-8601-Datumsstring – exaktes Datum:
<a-resource-page
base-url="https://anny.co"
resource="my-resource"
start="2025-06-15"
></a-resource-page>
Relativer Schlüsselwert – wird zum Render-Zeitpunkt aufgelöst:
Wert | Bedeutung |
| Aktueller Tag |
| Nächster Tag |
| Beginn der aktuellen Woche |
| Beginn der nächsten Woche |
| Beginn des aktuellen Monats |
| Beginn des nächsten Monats |
<a-resource-booking-panel
base-url="https://anny.co"
resource="my-resource"
start="tomorrow"
></a-resource-booking-panel>
Relative Werte werden überall unterstützt – außer bei a-resource-calendar und a-organization-calendar, die ISO 8601 erfordern.
end erwartet immer einen ISO-8601-Datumsstring.
Anpassungsoptionen nach Widget-Typ
Dieser Abschnitt dokumentiert die öffentlichen HTML-Attribute. Admin-generierte Snippets decken in der Regel die wichtigsten davon bereits ab.
Gemeinsame Attribute für Embed-Widgets
Gilt für Seiten-Widgets und Panel-Widgets. Nicht anwendbar auf Button-Widgets.
Attribut | Zweck |
| Erforderlich. anny-Basis-URL, z. B. |
| Widget-Sprache erzwingen. Wird es weggelassen, wird die Browser-Sprache verwendet |
| Feste iframe-Höhe, z. B. |
| Viewport-Höhe füllen ( |
| Abstand vom Viewport-Rand bei |
| Login vor der Buchung erforderlich |
| UUID des SSO-Identity-Providers |
| Eigenes Logo für die Lade-Animation |
Alle Embed-Widgets akzeptieren zusätzlich die Design-Attribute aus WIDGET_DESIGNING.md.
Organization-Widgets
a-organization-page
Attribut | Zweck |
| Erforderlicher Organization-Slug |
| Initialer Tab: |
|
|
|
|
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
| Ressourcenkategorie vorauswählen |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
| Filterleiste ausblenden |
| Karten-Umschalter ausblenden |
Hinweis:
Die Option „Kalender-Board" im Admin entspricht
calendar-view="list".
a-organization-calendar
Attribut | Zweck |
| Erforderlicher Organization-Slug |
|
|
| Kategorie-Slug |
| Initiales Startdatum (nur ISO 8601) |
| Initiales Enddatum |
a-organization-map
Attribut | Zweck |
| Erforderlicher Organization-Slug |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
Ressource-Widgets
a-resource-page
Attribut | Zweck |
| Erforderlicher Ressource-Slug |
| Service vorauswählen |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
| Kalender ausblenden |
a-resource-calendar
Attribut | Zweck |
| Erforderlicher Ressource-Slug |
| Service vorauswählen |
|
|
| Initiales Startdatum (nur ISO 8601) |
| Initiales Enddatum |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
a-resource-map
Attribut | Zweck |
| Erforderlicher Ressource-Slug |
| Service vorauswählen |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
a-resource-booking-panel
Attribut | Zweck |
| Erforderlicher Ressource-Slug |
| Service vorauswählen |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
Service-Widgets
a-service-page
Attribut | Zweck |
| Erforderlicher Service-Slug |
| Optionale Ressource vorauswählen |
a-service-booking-panel
Attribut | Zweck |
| Erforderlicher Service-Slug |
| Optionale Ressource vorauswählen |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Initiales Enddatum |
Subscription- und Package-Widgets
a-subscription-page
Attribut | Zweck |
| Erforderlicher Plan-Slug |
a-subscription-button
Attribut | Zweck |
| Erforderlicher Plan-Slug |
| Beschriftung des Trigger-Buttons |
a-package-page
Attribut | Zweck |
| Erforderlicher Package-Slug |
a-package-button
Attribut | Zweck |
| Erforderlicher Package-Slug |
| Beschriftung des Trigger-Buttons |
Button-Widgets
Gilt für:
a-organization-buttona-resource-buttona-service-buttona-subscription-buttona-package-buttona-modal-buttona-cart-modal-button
Gemeinsame Modal-Attribute
Attribut | Zweck |
|
|
|
|
| Benutzerdefinierte Dialog-Breite, z. B. |
| Titel im Modal-Header |
| Schließen per Klick außerhalb erlauben |
| Schließen-Button anzeigen |
| Barrierefreies Label für den Modal-Dialog |
Trigger-Attribute für Entity-Buttons
Gilt für:
a-organization-buttona-resource-buttona-service-buttona-subscription-buttona-package-button
Attribut | Zweck |
| Standard-Beschriftung des Buttons |
| Breite des Triggers |
| Hintergrundfarbe des Triggers |
| Textfarbe des Triggers |
a-modal-button ist anders:
kein
label-Propkeine eingebauten Trigger-Styling-Props
verwende ein eigenes Element im Slot als Trigger
Eigener Trigger (Slot)
Alle Button-Widgets akzeptieren einen Standard-Slot, der den eingebauten Trigger ersetzt. Nutze das, wenn du den Trigger selbst gestalten oder ein anderes Element als Button verwenden möchtest.
<!-- Eigener Button als Trigger -->
<a-resource-button
base-url="https://anny.co"
resource="my-resource"
>
<button class="my-cta-button">Schreibtisch buchen</button>
</a-resource-button>
<!-- Link als Trigger -->
<a-organization-button
base-url="https://anny.co"
organization="my-org"
>
<a href="#">Verfügbarkeit ansehen</a>
</a-organization-button>
<!-- a-modal-button erfordert immer einen Slot-Trigger -->
<a-modal-button
base-url="https://anny.co"
resource="my-resource"
>
<button>Buchung öffnen</button>
</a-modal-button>
Wenn ein Slot verwendet wird, werden label, button-background, button-text und button-width ignoriert. Klick- und Tastatursteuerung werden weiterhin vom Widget-Wrapper übernommen.
a-resource-button
Attribut | Zweck |
| Erforderlicher Ressource-Slug |
| Optionaler Service |
| Initiales Startdatum (siehe Start- und Enddatum) |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
a-service-button
Attribut | Zweck |
| Erforderlicher Service-Slug |
| Optionale Ressource vorauswählen |
a-organization-button
Attribut | Zweck |
| Erforderlicher Organization-Slug |
| Initialer Organization-Tab |
|
|
|
|
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
a-modal-button
Verwende diesen Button, wenn du einen eigenen Modal-Trigger ohne entity-spezifische Button-Komponente benötigst.
Attribut | Zweck |
| Ressource-Buchungsseite öffnen |
| Service vorauswählen (zusammen mit |
| Organization-Explore-Seite öffnen |
| Initialer Organization-Tab |
| Initiale Organization-Ansicht |
| Initiale Organization-Kalenderansicht |
| Ressource-Header ausblenden |
| Organization-Header ausblenden |
Hilfs-Widgets
a-cart-modal-button
Attribut | Zweck |
| Button-Beschriftung |
| Barrierefreies Dialog-Label |
|
|
| Dialog-Größen-Preset |
| Benutzerdefinierte Dialog-Breite |
| Titel im Modal-Header |
| Schließen per Klick außerhalb |
| Schließen-Button anzeigen |
| Trigger-Breite |
| Trigger-Höhe |
| Trigger-Hintergrund |
| Trigger-Text-/Icon-Farbe |
| Icon ein-/ausblenden |
a-login-button
Attribut | Zweck |
| Sprache des Login-Buttons |
| UUID des SSO-Providers |
| Trigger-Breite |
| Trigger-Höhe |
| Trigger-Hintergrund |
| Trigger-Text-/Icon-Farbe |
| Trigger-Eckenradius |
| Icon ein-/ausblenden |
a-my-bookings
Attribut | Zweck |
| Erforderlich |
| Optionale Sprache |
| Feste Höhe |
| Viewport-Höhe füllen |
| Header-Abstand für Fullscreen |
| UUID des SSO-Providers |
Hinweis:
a-my-bookingserfordert immer eine Authentifizierung.should-loginist nicht verfügbar, da Login obligatorisch ist.
Empfehlungen
Nutze zuerst das Admin-generierte Snippet und verfeinere es manuell nur wenn nötig.
Verwende Seiten-Widgets für dedizierte Buchungsseiten.
Verwende Panels für redaktionelle Seiten rund um den Buchungsfluss.
Verwende Button-Widgets, wenn die Buchung erst nach einem Klick sichtbar sein soll.
Platziere
a-login-buttonunda-cart-modal-buttonan stabilen, gut sichtbaren Stellen im UI.Bevorzuge
drawerfür Desktop-seitige Checkout-Flows undfullscreenfür mobile Erlebnisse.
