Nuxt
nuxt-driver-vue is a Nuxt 4 module for driver-vue. It installs DriverPlugin, auto-imports the composables, registers the components and adds the stylesheet.
pnpm add driver-vue nuxt-driver-vue// nuxt.config.ts
export default defineNuxtConfig({
modules: ["nuxt-driver-vue"],
driver: {
// Config merged under every useDriver() call, as the DriverPlugin
// `defaults`. It goes through runtime config, so only serializable values
// work; pass hooks and components in your code instead.
defaults: { showProgress: true },
// Register the components globally. (default: true)
components: true,
// Prefix of the component names. (default: "Driver")
prefix: "Driver",
// Add driver-vue/style.css to the app. Set to false to use your own
// stylesheet. (default: true)
css: true,
},
});runtimeConfig.public.driver.defaults is merged over driver.defaults, so the defaults can also be set per environment.
The registered components are DriverTour, DriverPopover, DriverOverlay, DriverBoxOverlay, DriverStage, DriverHints and DriverHintBeacon. The auto-imports are useDriver, createDriver, driver, useDriverPosition, provideDriver and injectDriver from driver-vue, and useHints, createHints and hints from driver-vue/hints.
A tour in a page
As in a Vue app, a <DriverTour /> in the same component renders the driver from useDriver():
<script setup lang="ts">
const { drive } = useDriver({
steps: [
{ element: "#welcome", popover: { title: "Welcome", description: "This is your dashboard." } },
{ element: "#reports", popover: { title: "Reports", description: "All reports are listed here." } },
],
});
onMounted(() => {
if (!localStorage.getItem("onboarded")) {
drive();
}
});
</script>
<template>
<!-- ... -->
<DriverTour />
</template>Call drive() from event handlers or onMounted. On the server the driver does nothing and drive() returns without effect, so a call during setup starts nothing.
One <DriverTour /> for the app
A <DriverTour /> in app.vue or a layout renders the app-wide driver. Pages use it through useDriver(config, { shared: true }), and a tour on it keeps running across navigation (see Multi-page tour).
<!-- app.vue -->
<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
<DriverTour />
</template>// in a page
const { drive } = useDriver({ steps: [/* ... */] }, { shared: true });Hints
<script setup lang="ts">
const { hints, show } = useHints({
hints: [{ element: "#export", popover: { title: "Export", description: "CSV or PDF." } }],
});
onMounted(show);
</script>
<template>
<DriverHints :hints="hints" />
</template>SSR
<DriverTour>and<DriverHints>render only after mount and teleport tobody, so there is no hydration mismatch.createDriver()outside a component also works on the server, where it returns an instance that does nothing.- Elements are looked up when a step is shown. For content that renders after a route change, use
waitForElement(see Interactive tour).
Without the module
Add a plugin that installs DriverPlugin and import the stylesheet:
// plugins/driver.ts
import { DriverPlugin } from "driver-vue";
import "driver-vue/style.css";
export default defineNuxtPlugin(nuxtApp => {
nuxtApp.vueApp.use(DriverPlugin, { components: true });
});Leave out the .client suffix so the plugin also runs on the server. Otherwise a <DriverTour /> without a driver prop finds no driver during server rendering and logs a warning in development. Without the module the composables are not auto-imported; import them from driver-vue.