Product Tour React component
A guided product tour: a spotlight glides from element to element over a dimmed page while a card beside it explains each one, with progress dots, Back, Next and Skip, arrow keys, and automatic placement on the side that has room.
About the Product Tour component
Product Tour walks people through an interface one step at a time. Each step dims the page except for a cut-out around the element being explained, and a card next to it shows a title, a short text, a step count and Back, Next and Skip buttons. The cut-out glides from one element to the next, and the card picks whichever side has room so it always stays on screen.
steps takes objects with a target CSS selector, a title, a body and a preferred placement; a step without a target shows a centered card, which suits a welcome or a goodbye. triggerLabel adds a button that starts the tour, or open and onOpenChange control it yourself. onStepChange reports the current step and onFinish runs when Done is pressed on the last one. padding sets the space around the cut-out, closeOnOverlayClick closes it from the dimmed area, and contained keeps it inside a positioned parent.
When to use it
Use Product Tour to walk new users through a dashboard or app the first time they arrive, or to point out a new feature after a release. Each step dims everything except the thing being explained.
Keep tours short (three to five steps) and let people skip. Use onFinish to remember that someone completed it so it doesn't come back.
Installation
Add the Product Tour component to your project with the shadcn CLI. It lands in components/product-tour.tsx as plain React + Tailwind CSS source you own and can edit.
npx shadcn@latest add @reactframe/product-tourOr copy the source by hand and install its dependencies:
npm install motion clsx tailwind-mergeProps
<ProductTour /> accepts 13 props, all optional.
| Prop | Type | Default |
|---|---|---|
| steps | { target?: string; title: string; body?: React.ReactNode; placement?: TourPlacement }[] | DEFAULT_STEPS |
| open | boolean | — |
| defaultOpen | boolean | false |
| onOpenChange | (open: boolean) => void | — |
| onStepChange | (index: number) => void | — |
| onFinish Called when the last step's Done button is pressed (not when skipped). | () => void | — |
| triggerLabel A button that starts the tour. Leave out and control it with open / onOpenChange. | string | — |
| padding Space between the highlight and its element, in px. | number | 6 |
| closeOnOverlayClick Close when the dimmed area is clicked. | boolean | false |
| showProgress | boolean | true |
| contained Look for targets inside, and draw over, the nearest positioned ancestor instead of the page. | boolean | false |
| theme | "dark" | "light" | "dark" |
- steps{ target?: string; title: string; body?: React.ReactNode; placement?: TourPlacement }[]Default: DEFAULT_STEPS
- openboolean
- defaultOpenbooleanDefault: false
- onOpenChange(open: boolean) => void
- onStepChange(index: number) => void
- onFinish
Called when the last step's Done button is pressed (not when skipped).
() => void - triggerLabel
A button that starts the tour. Leave out and control it with open / onOpenChange.
string - padding
Space between the highlight and its element, in px.
numberDefault: 6 - closeOnOverlayClick
Close when the dimmed area is clicked.
booleanDefault: false - showProgressbooleanDefault: true
- contained
Look for targets inside, and draw over, the nearest positioned ancestor instead of the page.
booleanDefault: false - theme"dark" | "light"Default: "dark"
Show all 13 propsShow fewer
| className | string | — |
- classNamestring
npm dependencies
Installed for you by the shadcn CLI.
Product Tour FAQ
- How do I point a step at an element?
- Give the element something selectable, like data-tour="search", and set that step's target to '[data-tour="search"]'. Leave target out for a centred welcome or goodbye step.
- Where does the card go?
- On the side you ask for with placement if there's room, otherwise below, above, right or left, whichever fits first. It's always kept inside the screen (or the container).
- Can it run inside a card or preview?
- Yes. Set contained and place the tour inside a positioned container; it then only looks for targets in that container and dims just that area.
- What happens if a step's target is not on the page?
- That step shows as a centered card without a cut-out, so the tour keeps going. Check the selector, or render the element before opening the tour.