Embed widget
Microsoft Bookings, on your own website
Paste your public Bookings page link and get a booking widget that matches your site. No Microsoft sign-in, no admin consent. Bookings still land in Outlook and Teams, and Microsoft still sends the invites.
Free plan, no card
The real widget, running against a demo business. Try a booking; nothing is sent to anyone.
How it works
Three steps, none of them in Microsoft 365 admin
- 01
Paste your Bookings page link
Copy the public link from the Bookings app; it usually starts with outlook.office.com/book/. BookingsXP loads your services, staff and open times from it.
- 02
Pick a template and your colours
Seven layouts for contact pages, sidebars, landing pages and full-width sections. Set the accent colour and light or dark mode; Pro adds fonts, radius, density and more.
- 03
Paste one snippet on your site
A script tag and one element, a plugin, or a package for your framework. Visitors book without leaving your page; Microsoft Bookings creates the appointment and sends the confirmation.
Templates
Seven layouts, three of them free
| Template | What it looks like | Best for | Plan |
|---|---|---|---|
| Classic | Month calendar beside the day's times — the layout visitors already know. | Contact and booking pages | Free |
| Compact | A scrolling day strip over a grid of times, built for sidebars and phones. | Sidebars, landing pages, mobile-heavy traffic | Free |
| Next available | The soonest open times as one list — one tap to pick, nothing to browse. | Sales calls and quick consultations | Free |
| Split | Your business and service details on the left, the calendar on the right. | Hosted booking pages and full-width sections | Pro |
| Week view | Seven days side by side so visitors compare times at a glance. | Clinics, salons and advisers with busy calendars | Pro |
| Guided | One question per step — service, person, day, time, details — with progress. | Many services or staff; highest completion on mobile | Pro |
| Service cards | Services as rich cards with duration and price, then a clean time picker. | Menus of services with prices | Pro |
Embed options
One script, then whatever your site speaks
HTML
Include the script once per page, then place the element where the widget should appear. Works in any HTML block: Webflow, Squarespace, Wix, Framer and HubSpot included.
Inline
The widget sits in the page and grows to fit its content.
<script src="https://bookingsxp.com/embed/v1.js" async></script>
<bookingsxp-widget widget="w_8fk2m1qz"></bookingsxp-widget>Popup button
A button that opens the widget in a dialog. Esc or the close button dismisses it.
<script src="https://bookingsxp.com/embed/v1.js" async></script>
<bookingsxp-widget widget="w_8fk2m1qz" mode="popup"
button-text="Book a call" accent="#0f766e"></bookingsxp-widget>Floating button
A button fixed to the bottom-right corner on every page that includes it.
<script src="https://bookingsxp.com/embed/v1.js" async></script>
<bookingsxp-widget widget="w_8fk2m1qz" mode="floating"
button-text="Book now" accent="#0f766e"></bookingsxp-widget>Plain iframe
No JavaScript at all. The widget works, but host-page events and attribution are not available.
<iframe src="https://bookingsxp.com/embed/w_8fk2m1qz" title="Book an appointment" loading="lazy"
style="width:100%;min-height:720px;border:0"></iframe>Div form
For site builders that strip unknown tags.
<script src="https://bookingsxp.com/embed/v1.js" async></script>
<div data-bookingsxp data-widget="w_8fk2m1qz"></div>Link only, no account
Use your Bookings link directly, no account. Free templates with the badge, and dataLayer events only: no dashboard analytics, GA4 or ad conversions.
<script src="https://bookingsxp.com/embed/v1.js" async></script>
<bookingsxp-widget
booking-url="https://outlook.office.com/book/Contoso@contoso.com/"
template="classic" accent="#0f766e"></bookingsxp-widget>Frameworks
Thin, typed wrappers that load the script once and render the element. Safe with server rendering and hydration.
React
// @bookingsxp/react (npm release pending — the script embed works in every framework today)
import { BookingsXPWidget } from "@bookingsxp/react";
export function Booking() {
return (
<BookingsXPWidget
widget="w_8fk2m1qz"
onBooked={(e) => console.log("booked", e.booking?.id)}
/>
);
}Next.js
// app/book/page.tsx — @bookingsxp/react (npm release pending — the script embed works in every framework today)
"use client";
import { BookingsXPWidget } from "@bookingsxp/react";
export default function BookPage() {
return <BookingsXPWidget widget="w_8fk2m1qz" redirectUrl="/thank-you" />;
}Vue 3
<!-- @bookingsxp/vue (npm release pending — the script embed works in every framework today) -->
<script setup>
import { BookingsXPWidget } from "@bookingsxp/vue";
const onBooked = (e) => console.log("booked", e.booking?.id);
</script>
<template>
<BookingsXPWidget widget="w_8fk2m1qz" @booked="onBooked" />
</template>Svelte 5
<!-- @bookingsxp/svelte (npm release pending — the script embed works in every framework today) -->
<script>
import BookingsXPWidget from "@bookingsxp/svelte";
</script>
<BookingsXPWidget widget="w_8fk2m1qz" onbooked={(e) => console.log(e.booking?.id)} />Astro
Server-rendered, ships no framework runtime.
---
// @bookingsxp/astro (npm release pending — the script embed works in every framework today)
import BookingsXPWidget from "@bookingsxp/astro/BookingsXPWidget.astro";
---
<BookingsXPWidget widget="w_8fk2m1qz" />WordPress
Install the plugin, then use the shortcode or the BookingsXP block in the editor. A settings page stores a default widget ID. Download the plugin (.zip)
Shortcode
[bookingsxp widget="w_8fk2m1qz"]
<!-- Or link-only, no account -->
[bookingsxp url="https://outlook.office.com/book/Contoso@contoso.com/"]
<!-- Popup button -->
[bookingsxp widget="w_8fk2m1qz" mode="popup" button_text="Book a call" accent="#0f766e"]Hosted booking page
Every saved widget also has its own page at bookingsxp.com/book/<widgetId> for email signatures, social bios and ads that need a link rather than an embed. Same template and colours, and it counts in your analytics.
Prefill
Skip the typing for people you already know
Attributes
For logged-in areas and personalised landing pages.
<bookingsxp-widget widget="w_8fk2m1qz"
name="Alex Rivera" email="alex.rivera@example.com"
phone="+1 555 0142" notes="Referred by Dr. Chen"
service="YOUR_SERVICE_ID"></bookingsxp-widget>JavaScript API
After a form on your page, or from your own data.
<script>
window.BookingsXP = window.BookingsXP || { q: [] };
BookingsXP.q.push(["render", "#booking", {
widget: "w_8fk2m1qz",
prefill: { name: "Alex Rivera", email: "alex.rivera@example.com" },
}]);
</script>
<div id="booking"></div>Hosted page URL
For links in emails and CRM sequences.
https://bookingsxp.com/book/w_8fk2m1qz?name=Alex%20Rivera&email=alex.rivera%40example.comThe loader hands prefill values to the widget inside the page. They are never added to the widget's iframe URL, so they do not end up in server logs or analytics tools.
Theming
Match your site, not ours
| Setting | Free | Pro and Business |
|---|---|---|
| Templates | Classic, Compact, Next available | All 7 |
| Accent colour | Included | Included |
| Light, dark or match the visitor | Included | Included |
| Business header and logo | Included | Included |
| Font (System, Geist, Serif, Rounded, Mono) | Not included | Included |
| Corner radius | Not included | Included |
| Density (comfortable or compact) | Not included | Included |
| Button style (solid, soft, outline) | Not included | Included |
| Background colour or transparent background | Not included | Included |
| “Powered by BookingsXP” badge | Shown | Removed |
No admin consent
Why IT does not need to approve it
What BookingsXP uses
- Your public Bookings page link, the one already on your website or in your email signature.
- The same open times and booking form that page shows to anyone.
- Microsoft Bookings itself to create each booking, so it appears in Outlook and Teams and Microsoft sends the confirmation and reminders.
What it never needs
- A Microsoft sign-in or a Microsoft 365 account for BookingsXP.
- An app registration, Graph permissions or tenant admin consent.
- Access to anyone's mailbox or calendar beyond what your public page already publishes.
Accessibility and performance
The details that decide whether people finish
- Visitor time zone
- Times always open in the visitor's own time zone. You can let visitors switch zone, and choose a 12 or 24 hour clock and the first day of the week.
- Auto-resize
- The widget reports its height to the page on every step, so there is no inner scrollbar and no fixed height to guess.
- Lazy loading
- Inline widgets load when they come near the viewport. The loader is about 8 KB gzipped and loads with async.
- Keyboard and screen readers
- The calendar is a labelled grid you move through with the arrow keys; month changes and the confirmation are announced; focus is visible throughout.
- Reduced motion
- Transitions are switched off when the visitor's system asks for reduced motion.
- Mobile first
- Every template adapts below its ideal width. Compact and Next available are built for sidebars and phones.
- Safe to embed
- The widget runs in its own iframe and talks to your page only through messages checked against both origins. You can restrict each widget to your own domains.
Want the tracking side too? Tracking and analytics
FAQ
Questions about the widget
Your calendar, on your site
Start with one widget on the Free plan. Keep Microsoft Bookings exactly as it is.