Tour
A guided tour that helps users understand the interface.
Anatomy
const tour = useTour({ steps: [...] })
<Tour.Root tour={tour}>
<Tour.Backdrop />
<Tour.Spotlight />
<Tour.Positioner>
<Tour.Content>
<Tour.Arrow>
<Tour.ArrowTip />
</Tour.Arrow>
<Tour.Title />
<Tour.Description />
<Tour.ProgressText />
<Tour.CloseTrigger />
<Tour.Actions>
<Tour.ActionTrigger />
</Tour.Actions>
</Tour.Content>
</Tour.Positioner>
</Tour.Root>
Examples
Step Types
Demonstrate all three step types in a single tour: dialog for welcome/completion, tooltip anchored to elements, and
floating for fixed-position content.
Progress
Display a visual progress indicator at the bottom of the tour content showing how far along the user is.
Skip
Allow users to skip the entire tour at any step by adding a skip action.
Keyboard Navigation
Enable arrow key navigation between tour steps using the keyboardNavigation prop.
Events
Listen to tour lifecycle events like onStepChange and onStatusChange to track user progress.
Wait for Click
Use the effect function with waitForEvent to wait for user interaction before proceeding to the next step.
Wait for Input
Create form tutorials that wait for users to enter valid input before advancing.
Wait for Element
Wait for dynamically rendered elements to appear in the DOM before showing a step.
Async
Load data asynchronously and update step content before displaying it using the effect function with show() and
update().
Guides
Step Types
The tour machine supports different types of steps, allowing you to create a diverse and interactive tour experience.
The available step types are defined in the StepType type:
-
tooltip: Displays the step content as a tooltip, typically positioned near the target element. -
dialog: Shows the step content in a modal dialog centered on screen, useful for starting or ending the tour. This usually don't have atargetdefined. -
floating: Presents the step content as a floating element, which can be positioned flexibly on the screen. This usually don't have atargetdefined. -
wait: A special type that waits for a specific condition before proceeding to the next step.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
placement: 'top-start',
target: () => document.querySelector('#target-1'),
title: 'Tooltip Step',
description: 'This is a tooltip step',
},
{
id: 'step-2',
type: 'dialog',
title: 'Dialog Step',
description: 'This is a dialog step',
},
{
id: 'step-3',
type: 'floating',
placement: 'top-start',
title: 'Floating Step',
description: 'This is a floating step',
},
{
id: 'step-4',
type: 'wait',
title: 'Wait Step',
description: 'This is a wait step',
effect({ next }) {
// do something and go next
// you can also return a cleanup
},
},
]
Actions
Every step supports a list of actions that are rendered in the step footer.Use the actions property to define each
action.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'dialog',
title: 'Dialog Step',
description: 'This is a dialog step',
actions: [{ label: 'Show me a tour!', action: 'next' }],
},
]
Tooltip Placement
Use the placement property to define the placement of the tooltip.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
placement: 'top-start',
// ...
},
]
Hide Arrow
Set arrow: false in the step property to hide the tooltip arrow. This is only useful for tooltip steps.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
arrow: false,
},
]
Hide Backdrop
Set backdrop: false in the step property to hide the backdrop. This applies to all step types except the wait step.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'dialog',
backdrop: false,
},
]
Effects
Step effects are functions that are called before a step is opened. They are useful for adding custom logic to a step.
This function provides the following methods:
next(): Call this method to move to the next step.show(): Call this method to show the current step.update(details: StepDetails): Call this method to update the details of the current step (say, after data has been fetched).
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'tooltip',
effect({ next, show, update }) {
fetchData().then((res) => {
// update the step details
update({ title: res.title })
// then show show the step
show()
})
return () => {
// cleanup fetch data
}
},
},
]
Wait
Wait steps are useful when you need to wait for a specific condition before proceeding to the next step.
Use the step effect function to perform an action and then call next() to move to the next step.
Note: You cannot call
show()in a wait step.
const steps: TourStepDetails[] = [
{
id: 'step-1',
type: 'wait',
effect({ next }) {
const button = document.querySelector('#button')
const listener = () => next()
button.addEventListener('click', listener)
return () => button.removeEventListener('click', listener)
},
},
]
Styling
Ensure the box-sizing is set to border-box for the means of measuring the tour target.
* {
box-sizing: border-box;
}
Ensure the body has a position of relative.
body {
position: relative;
}
API Reference
Props
Root
| Prop | Default | Type |
|---|---|---|
tour | UseTourReturn | |
immediate | booleanWhether to synchronize the present change immediately or defer it to the next frame | |
lazyMount | false | booleanWhether to enable lazy mounting |
onExitComplete | VoidFunctionFunction called when the animation ends in the closed state | |
present | booleanWhether the node is present (controlled by the user) | |
skipAnimationOnMount | false | booleanWhether to allow the initial presence animation. |
unmountOnExit | false | booleanWhether to unmount on exit. |
ActionTrigger
Renders a <button> element.
| Prop | Default | Type |
|---|---|---|
action | StepAction | |
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | action-trigger |
[data-type] | The type of the item |
[data-disabled] | Present when disabled |
Arrow
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| CSS Variable | Description |
|---|---|
--arrow-size | The size of the arrow |
--arrow-size-half | Half the size of the arrow |
--arrow-background | Use this variable to style the arrow background |
--arrow-offset | The offset position of the arrow |
ArrowTip
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Backdrop
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | backdrop |
[data-state] | "open" | "closed" |
[data-type] | The type of the item |
| CSS Variable | Description |
|---|---|
--tour-layer | The tour layer value for the Backdrop |
--layer-index | The index of the dismissable in the layer stack |
CloseTrigger
Renders a <button> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | close-trigger |
[data-type] | The type of the item |
Content
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | content |
[data-state] | "open" | "closed" |
[data-nested] | popover |
[data-has-nested] | popover |
[data-type] | The type of the item |
[data-placement] | The placement of the content |
[data-step] |
| CSS Variable | Description |
|---|---|
--layer-index | The index of the dismissable in the layer stack |
--nested-layer-count | The number of nested tours |
Control
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Description
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | description |
[data-placement] | The placement of the description |
Positioner
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | positioner |
[data-type] | The type of the item |
[data-placement] | The placement of the positioner |
| CSS Variable | Description |
|---|---|
--tour-layer | The tour layer value for the Positioner |
--reference-width | The width of the reference element |
--reference-height | The height of the root |
--available-width | The available width in viewport |
--available-height | The available height in viewport |
--x | The x position for transform |
--y | The y position for transform |
--z-index | The z-index value |
--transform-origin | The transform origin for animations |
ProgressText
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Spotlight
Renders a <div> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| CSS Variable | Description |
|---|---|
--tour-layer | The tour layer value for the Spotlight |
Title
Renders a <h2> element.
| Prop | Default | Type |
|---|---|---|
asChild | booleanUse the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
| Attribute | Description |
|---|---|
[data-scope] | tour |
[data-part] | title |
[data-placement] | The placement of the title |
Context
API
| Property | Type |
|---|---|
open | booleanWhether the tour is open |
totalSteps | numberThe total number of steps |
stepIndex | numberThe index of the current step |
step | StepDetailsThe current step details |
hasNextStep | booleanWhether there is a next step |
hasPrevStep | booleanWhether there is a previous step |
firstStep | booleanWhether the current step is the first step |
lastStep | booleanWhether the current step is the last step |
addStep | (step: StepDetails) => voidAdd a new step to the tour |
removeStep | (id: string) => voidRemove a step from the tour |
updateStep | (id: string, stepOverrides: Partial<StepDetails>) => voidUpdate a step in the tour with partial details |
setSteps | (steps: StepDetails[]) => voidSet the steps of the tour |
setStep | (id: string) => voidSet the current step of the tour |
start | (id?: string) => voidStart the tour at a specific step (or the first step if not provided) |
isValidStep | (id: string) => booleanCheck if a step is valid |
isCurrentStep | (id: string) => booleanCheck if a step is visible |
next | VoidFunctionMove to the next step |
prev | VoidFunctionMove to the previous step |
getProgressText | () => stringReturns the progress text |
getProgressPercent | () => numberReturns the progress percent |