Skip to main content

Vue guide

Install the app-scoped runtime and use typed definitions in plain Vue.

Use Nuxt Tour in plain Vue

Import the Vue entry and the theme:

ts
import { createApp } from 'vue'
import { createTourPlugin } from '@lupinum/nuxt-tour/vue'
import '@lupinum/nuxt-tour/style.css'
import App from './App.vue'
import onboarding from './tours/onboarding'

const app = createApp(App)
app.use(createTourPlugin({ tours: [onboarding] }))
app.mount('#app')

Pass the definition to useTour() so its step IDs remain literal:

ts
const onboardingTour = useTour(onboarding)
await onboardingTour.goTo('create-project')

The same plugin object can be installed on multiple Vue applications. Each app gets an independent runtime, targets, listeners, and active session.

Vue Router

Pass a Vue Router instance when a definition contains route:

ts
app.use(router)
app.use(createTourPlugin({ tours: [onboarding], router }))

A route without a router rejects with ROUTER_NOT_CONFIGURED; it is never silently ignored. When the router provides afterEach, navigation outside the tour cancels the active or starting session.

Dynamic targets

vue
<script setup lang="ts">
const saveButton = useTemplateRef<HTMLButtonElement>('saveButton')
useTourTarget('save-project', saveButton)
</script>

<template>
  <button ref="saveButton">
    Save project
  </button>
</template>

Use v-tour-target="'save-project'" for template targets and useTourTarget() for dynamic refs. Both register the semantic ID with the current Vue application, so multiple apps on one page stay isolated. Duplicate visible registrations fail clearly. HTML and SVG elements are supported. Use an explicit { selector } target only for third-party or legacy markup outside Vue.