Frameworks
Microsoft Bookings widget for Vue and Nuxt
@bookingsxp/vue is a Vue 3 component around the BookingsXP custom element. It loads the script on mount, forwards widget events as Vue emits, and renders cleanly during server rendering in Nuxt.
- Plan
- Plan: FreeWorks on every plan, including Free ($0, no card).
- In short
- @bookingsxp/vue: a Vue 3 component with @event and @booked, safe for Nuxt server rendering.
- Microsoft Bookings
- Stays your system of record. Bookings land in Outlook and Teams and Microsoft sends the invites and reminders.
How it works
What happens with Vue
- The component renders <bookingsxp-widget> with a render function and calls the loader in onMounted, so nothing runs on the server except the markup.
- Props mirror the embed options: widget, bookingUrl, mode, buttonText, template, theme, accent, radius, service, staff, locale, prefill, redirectUrl, minHeight, lazy, hideHeader and baseUrl.
- It emits event for every step and booked for booking_completed, and removes its listeners in onBeforeUnmount.
Setup
Set up Vue
4 steps. Names of menus and buttons are as they appear today; vendors rename things, so look for the closest match.
Step 1: Install
Add the package.
Shell npm i @bookingsxp/vue # npm release pending — until then use the script embedStep 2: Use it in a component
Import the named export (a default export is also provided).
Vue <script setup lang="ts"> import { BookingsXPWidget, type WidgetEvent } from "@bookingsxp/vue"; function onBooked(e: WidgetEvent) { console.log("booked", e.booking?.id); } </script> <template> <BookingsXPWidget widget="w_8fk2m1qz" theme="auto" @booked="onBooked" /> </template>Step 3: Tell Vue the element is custom
So Vue does not try to resolve bookingsxp-widget as a component, mark it as a custom element in your compiler options.
vite.config.ts vue({ template: { compilerOptions: { isCustomElement: (tag) => tag === "bookingsxp-widget" }, }, })Step 4: Nuxt: register it where you need it
Import the component in the page that shows it. It is SSR-safe, so no <ClientOnly> wrapper is required.
Outcomes and caveats
What you get
The result
- A typed Vue 3 component with emits for the whole funnel.
- Server rendering without hydration warnings.
- The same dataLayer and pixel events on the page as the plain script embed.
Good to know
Limits and caveats
- Vue 3 only; there is no Vue 2 build.
- A popup opened from your own button needs window.BookingsXP.open after the script has loaded; the JavaScript API docs show how.
- Premium templates need a saved Pro widget.
FAQ
Vue questions
Something not covered? Email hello@bookingsxp.com.
Start free, no card
One widget, three templates, GTM and GA4 events and attribution in every booking. No card, no time limit.