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.
  1. Step 1: Install

    Add the package.

    Shell
    npm i @bookingsxp/vue   # npm release pending — until then use the script embed
  2. Step 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>
  3. 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" },
      },
    })
  4. 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.