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.
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
Eight 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, the WordPress plugin, or the hosted page link. Visitors book without leaving your page; Microsoft Bookings creates the appointment and sends the confirmation.
Eight layouts, four 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 |
| Profile | Your photo, a short bio and what you'll cover beside the calendar. | Consultants, advisers, coaches and Bookings with me pages | 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 |
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. 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. Their npm release is pending; until then, use the script embed.
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"]A booking page at your own address
- Your own address
- Choose the name after
bookingsxp.com/book/in the widget's Install tab: lowercase letters, numbers and hyphens, 3 to 40 characters. The widget's original link keeps working and redirects to it. Microsoft trademarks and reserved words cannot be used. - Search indexing, if you want it
- Hosted pages are kept out of search engines by default. Turn on “Let search engines index this page” and it becomes indexable and is listed in the sitemap.
- Tracked like the embed
- Add UTM tags to the link, for example ?utm_source=newsletter, and they flow into the booking notes and your reports.
- Prefill and preselect by URL
- Add name, email, phone or notes to prefill the form, and service or staff to open on one service or one person.

Skip the typing for people you already know
Attributes
For signed-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/brightwater?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.
Match your site
| Setting | Free | Pro and Business |
|---|---|---|
| Templates | Classic, Compact, Next available, Profile | All 8 |
| 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 (0–28 px) | 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 |
Things Microsoft's booking page can't do
- Daily booking cap
- Set “Max bookings per day” and the widget stops offering a day once that many bookings have come through it for that day, counted in your business time zone. Useful for new-patient slots or a limited offer. Microsoft's own booking page is not capped.
- Help text under questions
- Add a line of guidance under any custom question from your Bookings page, such as “Include your policy number if you have one”. Microsoft Bookings shows only the question.
- Email typo check
- When a visitor types a common domain typo such as gmial.com or outlook.con, the widget suggests the fix in one tap before the booking is sent, so the confirmation reaches them.
- Per-staff and per-service links
- Open the widget or hosted page on one person or one service with the staff and service attributes or URL parameters. Microsoft Bookings has no link for a single staff member.
Per-staff link
<!-- One person, one service -->
<bookingsxp-widget widget="w_8fk2m1qz"
staff="YOUR_STAFF_ID" service="YOUR_SERVICE_ID"></bookingsxp-widget>
<!-- The same on the hosted page -->
https://bookingsxp.com/book/brightwater?staff=YOUR_STAFF_IDWhy 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
- 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 designed 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
Questions about the widget
Your calendar, on your site
Start with one widget on the Free plan. Keep Microsoft Bookings exactly as it is.
No Microsoft sign-in or admin consent. Free plan, no card.