Embed Widget
Foglalási widget beágyazása saját weboldalba.
Áttekintés#
A Bokko embed widget lehetővé teszi, hogy a teljes foglalási folyamatot beágyazd bármilyen weboldalba — saját domain alatt, a látogatók elhagyása nélkül.
- Két megjelenítési mód: inline (beágyazott iframe) és popup (modális overlay)
- Egyetlen script tag:
https://booking.bokko.app/bokko-widget.js - Automatikus fallback: ha a widget nem töltődik be, a látogató közvetlenül a foglalási oldalra jut
- postMessage kommunikáció: eseményeken keresztül értesülhetsz a foglalás állapotáról
Gyors indulás#
Inline mód#
A legegyszerűbb beágyazás — a widget közvetlenül megjelenik az oldalon:
<div class="bokko-widget" data-mode="inline" data-slug="my-salon">
<a href="https://foglalas.bokko.app/my-salon">Foglalás megnyitása</a>
</div>
<script src="https://booking.bokko.app/bokko-widget.js"></script>Popup mód#
A foglalási folyamat egy gombkattintásra nyíló modális ablakban jelenik meg:
<div class="bokko-widget" data-mode="popup" data-slug="my-salon"
data-button-text="Foglalj időpontot!">
<a href="https://foglalas.bokko.app/my-salon">Foglalj időpontot!</a>
</div>
<script src="https://booking.bokko.app/bokko-widget.js"></script><div> belsejében elhelyezett <a> tag kettős célt szolgál: fallback linkként működik, ha a JavaScript nem töltődik be, és noscript környezetben is elérhető marad a foglalási oldal.Megjelenítési módok#
Inline#
Beágyazott iframe, amely közvetlenül az oldalon jelenik meg a <div> helyén.
- Teljes szélességben kitölti a szülő elemet
- Minimum magasság: 500px
- Automatikus magasságigazítás: a widget
resizeüzenetet küld a tartalommagasság változásakor, az iframe magassága ehhez igazodik - Szegély nélkül jelenik meg, az oldal természetes részeként
Popup#
Modális overlay, amely gombkattintásra nyílik.
- Maximális szélesség: 580px, magasság: 90vh
- Középre igazított, háttér overlay-jel
- 640px alatti képernyőszélességnél teljes képernyős megjelenés (mobil optimalizáció)
- Bezárási lehetőségek:
- Háttérre (backdrop) kattintás
- Escape billentyű
- X gomb a jobb felső sarokban
Data attribútumok#
A widget viselkedését a <div> elemen elhelyezett data-* attribútumokkal konfigurálhatod:
| Attribútum | Kötelező | Értékek | Alapértelmezett | Leírás |
|---|---|---|---|---|
data-slug | Igen | string | — | A szolgáltató URL slug-ja |
data-mode | Nem | inline, popup | inline | Megjelenítési mód |
data-button-text | Nem | string | Foglalj időpontot! | Popup gomb szövege (csak popup módban) |
A data-slug az egyetlen kötelező attribútum. Ez határozza meg, melyik szolgáltató foglalási felülete jelenik meg. A slug megegyezik a szolgáltató publikus URL-jében szereplő azonosítóval (pl. foglalas.bokko.app/my-salon → data-slug="my-salon").
Események (postMessage)#
A widget a window.postMessage API-n keresztül kommunikál a befogadó oldallal. Minden üzenet tartalmazza a source, version és type mezőket.
Elérhető események#
| Esemény | Payload | Leírás |
|---|---|---|
ready | — | A widget betöltődött és megjeleníthető |
booking:confirmed | { slug: string } | A foglalás sikeresen létrejött |
booking:closed | — | A felhasználó bezárta a widgetet (popup mód) |
resize | { height: number } | A tartalom magassága megváltozott (csak inline mód) |
Üzenetformátum#
Minden postMessage az alábbi struktúrát követi:
{
"source": "bokko-widget",
"version": 1,
"type": "booking:confirmed",
"payload": { "slug": "my-salon" }
}Események figyelése#
window.addEventListener('message', (event) => {
if (event.data?.source !== 'bokko-widget') return;
if (event.data.version !== 1) return;
switch (event.data.type) {
case 'ready':
console.log('Widget betöltődött');
break;
case 'booking:confirmed':
console.log('Sikeres foglalás:', event.data.payload.slug);
// pl. analytics event küldése, köszönőoldal megjelenítése
break;
case 'booking:closed':
console.log('Widget bezárva');
break;
case 'resize':
console.log('Új magasság:', event.data.payload.height);
break;
}
});event.data.source és event.data.version mezőket az üzenet feldolgozása előtt. A postMessage API-n keresztül bármilyen forrásból érkezhet üzenet — a forrás- és verzióellenőrzés nélkül más scriptek üzeneteit is feldolgozhatod véletlenül.Fallback viselkedés#
A widget beépített fallback mechanizmussal rendelkezik arra az esetre, ha a beágyazott iframe nem töltődik be:
- A script inicializálja az iframe-et
- Várakozás a
readyeseményre — maximum 8 másodpercig - Ha a
readynem érkezik meg időben, a widget visszaáll a fallback linkre - A fallback URL:
https://foglalas.bokko.app/{slug}
<a> taget a widget <div>-en belül a megfelelő foglalási URL-lel. Ez biztosítja, hogy JavaScript nélküli környezetben (noscript) és betöltési hiba esetén is elérhető marad a foglalási felület.Biztonsági modell#
Origin validáció#
A host oldali widget script kizárólag a Bokko booking origin-ekről érkező üzeneteket fogadja el:
https://booking.bokko.apphttps://foglalas.bokko.app
Bármely más origin-ról érkező postMessage üzenet csendben elvetésre kerül. Ez a lista a widget JS-ben hardkódolt — egyéb origin (saját staging, lokális dev iframe hosztolás) v1-ben nem támogatott.
Handshake protokoll#
A widget egy egyszerű, iframe-által kezdeményezett handshake-et használ:
- Az iframe
readyüzenetet küld, miután betöltődött - A host validálja az origin-t (ld. fent), majd
handshakeüzenetet küld vissza az iframe-nektargetOrigin: https://booking.bokko.appparaméterrel - A további kommunikáció ezen az ellenőrzött csatornán folyik
A ready előtt érkező üzeneteket az iframe figyelmen kívül hagyja; a ready után a host csak azokat dolgozza fel, amelyek tartalmazzák a source: 'bokko-widget' és version: 1 mezőket.
PII minimalizáció#
A postMessage üzenetek kizárólag a szolgáltató slug-ját tartalmazzák. A widgeten keresztül nem kerül átadásra:
- Vendég személyes adat (név, e-mail, telefonszám)
- Foglalás azonosító
- Fizetési információ
Akadálymentesség#
A widget az alábbi akadálymentességi funkciókat biztosítja:
- Focus trap popup módban: a Tab billentyű a modális ablakon belül ciklikusan navigál, nem lép ki a háttérre
- Escape billentyű bezárja a popup-ot
- Backdrop kattintás bezárja a popup-ot
- ARIA attribútumok: a bezáró gomb
aria-labelcímkével rendelkezik - A fallback
<a>link biztosítja az alapszintű hozzáférhetőséget képernyőolvasók számára is
Tesztelés#
Lokális fejlesztés#
A widget tesztelhető bármilyen origin-ról szolgált host oldalról (a host page origin-jét nem ellenőrzi a widget) — viszont az iframe-et kiszolgáló booking app HTTPS-en, a booking.bokko.app domain alól töltődik be. Lokálisan:
- Tölts be egy HTML fájlt bármilyen módon (
file://,localhost, custom domain) — abokko-widget.jsfutni fog - Az iframe és a
postMessagekommunikáció csak akkor működik, ha az iframe-et a hivatalosbooking.bokko.app(vagyfoglalas.bokko.app) szolgálja ki - Saját stagingre / saját bookingapp példányra szabás v1-ben nem támogatott (az
ALLOWED_ORIGINSlista hardkódolt)
Hibakeresés#
- Network tab (böngésző DevTools): ellenőrizd, hogy a
bokko-widget.jssikeresen betöltődik-e (200 OK) - Console tab: figyelemmel kísérheted a postMessage eseményeket az események figyelése szekcióban leírt listener segítségével
- Elements tab: ellenőrizd, hogy az iframe megjelenik-e a
.bokko-widgetdiv-en belül
Ellenőrzőlista#
- [ ] A
data-slugattribútum helyes szolgáltatóra mutat - [ ] A fallback
<a>link megfelelő URL-t tartalmaz - [ ] Popup módban a gomb megjelenik és kattintható
- [ ] A
readyesemény megérkezik a console-ban - [ ] Mobil nézetben (640px alatt) a popup teljes képernyős
- [ ] Az Escape billentyű bezárja a popup-ot