Create a tour
Learn how to create a tour in your Nuxt project using the nuxt-tour module.
Add the component
Add <VTour /> to your page and pass an array of steps:
app.vue
<template>
<div>
<h1 id="welcome">Welcome</h1>
<button class="cta">Get started</button>
<footer data-step="contact">Contact us</footer>
<VTour :steps="steps" />
</div>
</template>
<script lang="ts" setup>
import type { TourStep } from "#nuxt-tour/types";
const steps: TourStep[] = [
{
target: "#welcome",
title: "Welcome to the app",
body: "This is your dashboard. Let us show you around.",
},
{
target: ".cta",
title: "Get started",
body: "Click here whenever you are ready.",
popperConfig: { placement: "bottom" },
},
{
target: '[data-step="contact"]',
title: "Need help?",
body: "Reach out to us any time.",
},
];
</script>
- The
targetprop must be a valid CSS selector, a reactive ref, or a directHTMLElement. - The target element must already be in the DOM before the tour starts.
- If a target cannot be found, the tooltip is centred on the screen instead.
Starting the tour
Three ways to start a tour:
Auto-start on mount
Pass the auto-start prop and the tour begins as soon as the component mounts:
<template>
<VTour auto-start :steps="steps" />
</template>
Add start-delay (ms) to wait before showing the first step:
<template>
<VTour auto-start :start-delay="500" :steps="steps" />
</template>
Manual start via template ref
<template>
<button @click="tour?.startTour()">Start tour</button>
<VTour ref="tour" :steps="steps" />
</template>
<script lang="ts" setup>
import { VTour } from "#components";
const tour = useTemplateRef<InstanceType<typeof VTour>>("tour");
</script>
Start via the composable
useTour lets you control any named tour from any component — even before <VTour /> has mounted:
<template>
<button @click="start()">Start tour</button>
<VTour name="onboarding" :steps="steps" />
</template>
<script lang="ts" setup>
const { start, isPlayed, reset } = useTour("onboarding");
</script>
If start() is called before the component mounts it is queued and fires automatically once the component is ready.
Controlling localStorage
Use the save-to-local-storage prop to choose how progress is persisted:
default<template>
<VTour save-to-local-storage="step" :steps="steps" />
</template>
TTL — re-show after N days
<template>
<!-- Show the tour again after 30 days -->
<VTour :ttl="30" :steps="steps" />
</template>
Version-based reset
Bump storageVersion in your nuxt.config to force all users to see the tour again:
nuxt.config.ts
export default defineNuxtConfig({
tour: { storageVersion: "v2" },
});
Multiple tours
Each <VTour /> with a unique name prop is tracked independently in localStorage:
<template>
<VTour name="onboarding" :steps="onboardingSteps" />
<VTour name="feature-x" :steps="featureSteps" />
</template>
Control each tour from anywhere via the composable:
const onboarding = useTour("onboarding");
const featureX = useTour("feature-x");
onboarding.reset(); // clear storage and restart
featureX.markUnplayed(); // mark as not played without restarting