Skip to content

Embed widget reference

For a business-owner guide, see Embed booking on your website.

Replace {origin} with your BUKMI app URL (e.g. https://app.bukmi.pl).

ModeURL pattern
Hub{origin}/embed/b/{business-slug}
Service{origin}/embed/b/{business-slug}/{service-slug}
Pay (breakout){origin}/embed/b/{business-slug}/pay/{confirmation-token}
Thank you{origin}/embed/b/{business-slug}/confirmed/{confirmation-token}

Query params: ?accent=%237c6cf2&lang=pl (optional).

Host the script from your BUKMI instance:

<script
src="https://app.bukmi.pl/embed.js"
data-business="your-business-slug"
data-mode="inline"
data-target="#bukmi-embed"
async
></script>
<div id="bukmi-embed"></div>
AttributeRequiredDescription
data-businessyesBusiness slug (/b/{slug}).
data-modenoinline (default), popup, or use direct iframe without script.
data-targetinlineCSS selector for container (default #bukmi-embed).
data-servicenoService slug - opens that service directly.
data-accentnoHex accent colour (e.g. #7c6cf2).
data-langnopl or en for guest UI.
data-button-labelpopupLabel for trigger button (default “Book now”).
data-button-classpopupExtra CSS class on trigger button.
data-button-stylepopupInline CSS on trigger button.
data-titlenoAccessible title on iframe.

Popup mode inserts the trigger button immediately after the script tag.

The business owner must whitelist each parent origin in My offer → Embed (e.g. https://www.client-salon.com). Without a match, /embed/... responses return 403.

Owner preview: append ?preview=1 while logged in as an editor (bypasses allowlist for testing).

The iframe posts JSON messages to the parent. Listen on window:

window.addEventListener('message', (event) => {
if (event.origin !== 'https://app.bukmi.pl') return;
const { type, ...detail } = event.data || {};
switch (type) {
case 'bukmi:ready':
// iframe loaded; detail.height
break;
case 'bukmi:resize':
// detail.height - auto-resize inline iframe
break;
case 'bukmi:step':
// detail.step - guest wizard step ("1" | "2")
break;
case 'bukmi:booking-created':
// detail.bookingId, confirmationToken, awaitingPayment, series?
break;
case 'bukmi:booking-confirmed':
// detail.bookingId or bookingSeriesId - popup auto-closes
break;
case 'bukmi:payment-breakout':
// detail.stripeUrl - parent may navigate top window to Stripe
window.location = detail.stripeUrl;
break;
}
});

The bundled embed.js handles bukmi:resize, bukmi:payment-breakout, and bukmi:booking-confirmed automatically.

window.addEventListener('message', (event) => {
if (event.origin !== 'https://app.bukmi.pl') return;
if (event.data?.type === 'bukmi:booking-confirmed') {
gtag('event', 'purchase', { transaction_id: event.data.confirmationToken });
}
});

Your site must allow:

  • script-src - origin of embed.js
  • frame-src (or child-src) - BUKMI app origin for the iframe

BUKMI sets Content-Security-Policy: frame-ancestors 'self' https://your-site.com on embed responses.

Stripe Checkout cannot run inside an iframe. The pay route returns a short HTML page that sets window.top.location to Stripe and emits bukmi:payment-breakout. After payment, Stripe redirects to the embed thank-you URL on the BUKMI domain.