Tour
UtilityStep-by-step product tour overlay.
Preview
Product tour for onboarding. Highlights UI elements with tooltips step by step.
Step 1 of 2
Welcome
Click here to start
Usage
example.jsx
import { Tour } from "@/components/ui/tour";
export default function Example() {
return <Tour />;
}Source Code
Copy this file into components/ui/tour.jsx in your project.
tour.jsx
"use client";
import { forwardRef, useState, useEffect } from "react";
import { cn } from "@/lib/utils";
const Tour = forwardRef(({ className, steps = [], onComplete, ...props }, ref) => {
const [current, setCurrent] = useState(0);
const step = steps[current];
if (!step) return null;
return (
<div ref={ref} className={cn("fixed inset-0 z-[9999]", className)} {...props}>
<div className="absolute inset-0 bg-black/50" onClick={onComplete} />
<div className="absolute left-1/2 top-1/2 w-80 -translate-x-1/2 -translate-y-1/2 rounded-lg border bg-popover p-6 shadow-xl">
<div className="text-xs text-muted-foreground">Step {current + 1} of {steps.length}</div>
<h4 className="mt-1 font-semibold">{step.title}</h4>
<p className="mt-2 text-sm text-muted-foreground">{step.description}</p>
<div className="mt-4 flex justify-between">
<button onClick={() => setCurrent(Math.max(0, current - 1))} disabled={current === 0}
className="rounded-md border px-3 py-1.5 text-sm disabled:opacity-50"
>Back</button>
<button onClick={() => current < steps.length - 1 ? setCurrent(current + 1) : onComplete?.()}
className="rounded-md bg-primary px-3 py-1.5 text-sm text-primary-foreground"
>{current === steps.length - 1 ? "Finish" : "Next"}</button>
</div>
</div>
</div>
);
});
Tour.displayName = "Tour";
export { Tour };
Quick Install
Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.
npm install clsx tailwind-merge