Drive the user’s focus across your Vue 3 app using [Driver.js](https://driverjs.com/) — with full support for Vuetify, Options API, and Composition API.
npm install @gfmois/vue3-driverThis plugin solves the real problems of using Driver.js in component-based UIs:
DOM resolution, lifecycle cleanup, multiple tours, and predictable ordering.
bash
pnpm add vue3-driver driver.js
or
npm install vue3-driver driver.js
`Import Driver.js styles:
`ts
import 'driver.js/dist/driver.css'
`Usage
Install the plugin
`ts
import { createApp } from 'vue'
import { Vue3DriverPlugin } from 'vue3-driver'createApp(App)
.use(Vue3DriverPlugin, {
// Driver.js options
// https://driverjs.com/docs/configuration
animate: true,
defaultScope: 'default',
})
.mount('#app')
`Declare steps with the directive
`html
v-driver-step="{ popover: { title: 'Header', description: 'This is the header' }, index: 0 }"
>
My App
v-driver-step="{ popover: { title: 'Main', description: 'Main content' }, index: 1 }"
>
Content...
v-driver-step="{ popover: { title: 'Footer', description: 'The footer' }, index: 2 }"
>
2026
`
Steps are automatically registered and removed when components mount and unmount.Start the tour
$3
`ts
`$3
`ts
export default {
mounted() {
this.$driver.start()
}
}
`Vuetify support (target)
Vuetify components do not expose their real DOM nodes reliably.
Use target to tell the plugin which element should be highlighted.
`html
class="save-btn"
v-driver-step="{
target: '.save-btn',
popover: { title: 'Save', description: 'Click here to save' },
index: 0
}"
>
Save
`
target supports:
`ts
type StepTarget =
| string
| Element
| ((host: Element) => Element | null)
`Scopes (multiple tours)
You can define independent tours using scopes.
`html
class="profile-btn"
v-driver-step="{
scope: 'profile',
target: '.profile-btn',
popover: { title: 'Profile', description: 'Your account' },
index: 0
}"
/>
`
Start a specific tour:
`ts
driver.start('profile')
`Indexing
Steps can be ordered in two ways:
$3
`html
`
Steps without an index are appended after indexed ones.$3
`ts
interface VueDriverApi {
start(scope?: string, stepIndex?: number): void
refresh(scope?: string): void
clear(scope?: string): void
}
`start(scope?, index?)
> Builds and starts the tour for a scope.refresh(scope?)
> Rebuilds the steps without starting.clear(scope?)
> Removes all steps from a scope (or all scopes).Automatic cleanup
When a component with v-driver-step` is unmounted: