Skip to content

Nuxt

@zaptime/vue3 works in Nuxt 3 without a module or plugin. Two things matter: the stylesheet must be registered globally, and the component must render on the client only because its state depends on window, navigator and the visitor's timezone.

1. Install

sh
pnpm add @zaptime/vue3

2. Register the stylesheet

ts
// nuxt.config.ts
export default defineNuxtConfig({
  css: ["@zaptime/vue3/dist/style.css"],
});

3. Render inside <ClientOnly>

vue
<!-- pages/book.vue -->
<template>
  <ClientOnly>
    <ZaptimeCalendar :config="config" @booking-confirmed="onBooked" />
    <template #fallback>
      <div style="min-height: 360px" />
    </template>
  </ClientOnly>
</template>

<script setup lang="ts">
import { ZaptimeCalendar } from "@zaptime/vue3";
import type { ZaptimeConfig } from "@zaptime/vue3";
import type { ReservationResponse } from "@zaptime/core";

const config: ZaptimeConfig = {
  token: useRuntimeConfig().public.zaptimeToken,
};

function onBooked(reservation: ReservationResponse) {
  navigateTo({ path: "/thank-you", query: { uuid: reservation.data.uuid } });
}
</script>

The fallback with the same footprint avoids layout shift while the client bundle loads.

Reschedule page

Zaptime's reschedule emails link to a page of your choosing with the reservation UUID in the query string. Read it and pass reservationUuid:

vue
<!-- pages/reschedule.vue -->
<script setup lang="ts">
const route = useRoute();

const config = computed(() => ({
  token: useRuntimeConfig().public.zaptimeToken,
  reservationUuid: String(route.query.reservation ?? ""),
}));
</script>

<template>
  <ClientOnly>
    <ZaptimeCalendar :config="config" />
  </ClientOnly>
</template>

See Rescheduling.

Multiple pages with calendars

Calendar state is module-level and survives client-side navigation. Give each page's calendar its own calendar-id so the second page does not inherit the first page's selection.

Troubleshooting

  • window is not defined / navigator is not defined in the server log: the component or a @zaptime/core composable ran during SSR. Move it inside <ClientOnly> or onMounted.
  • Calendar renders as an unstyled list: the stylesheet is missing from css in nuxt.config.ts.
  • ESM errors at build time: add @zaptime/vue3 to build.transpile only when the build reports such an error.

A runnable example lives in the monorepo at examples/nuxt-example.