react-tourlight

API Reference

Complete reference for all react-tourlight components, hooks, and types.

SpotlightProviderProps

Props for the <SpotlightProvider> component that wraps your application and manages all tour state.

PropTypeDefaultDescription
childrenReactNode--Your application content
theme'light' | 'dark' | 'auto' | SpotlightTheme'light'Theme preset or custom theme object
overlayColorstring'rgba(0, 0, 0, 0.5)'Overlay background color (with alpha)
transitionDurationnumber300Transition duration in milliseconds
escToDismissbooleantrueWhether pressing Escape dismisses the tour
overlayClickToDismissbooleantrueWhether clicking the overlay dismisses the tour
showProgressbooleantrueWhether to show a progress bar
showSkipbooleantrueWhether to show a skip button
labelsSpotlightLabels--Custom labels for i18n
onComplete(tourId: string) => void--Called when any tour completes
onSkip(tourId: string, stepIndex: number) => void--Called when any tour is skipped
onStateChange(tourId: string, state: TourState) => void--Called with tour state for persistence
initialStateRecord<string, TourState>--Initial state for restoring persisted tours
waitForElementTimeoutnumber5000Default max time (ms) to wait for a step's target to appear in the DOM before skipping to the next step. Overridable per-step via SpotlightStep.timeout
persistboolean | SpotlightStorage--Enable cross-navigation persistence. true uses localStorage; pass a custom SpotlightStorage for other backends. Off by default
persistKeystring'react-tourlight'Storage key used when persist is enabled
persistMaxAgenumber--Discard persisted state older than this many ms (staleness guard)
resumebooleantrueAuto-resume a persisted, still-active tour on mount
navigate(path: string) => void--Called with a step's route when it doesn't match the current location. Plug in your router
isRouteActive(route: string, pathname: string) => booleanbuilt-inCustom route matcher (overrides the exact / :param / * default)

SpotlightTourProps

Props for the <SpotlightTour> component that registers a tour's steps with the provider.

PropTypeDefaultDescription
idstring--Unique identifier for this tour
stepsSpotlightStep[]--Array of step configurations
onComplete() => void--Called when this tour completes
onSkip(stepIndex: number) => void--Called when this tour is skipped
renderTooltip(props: TooltipRenderProps) => ReactNode--Custom tooltip render function

SpotlightStep

Configuration for a single tour step.

PropTypeDefaultDescription
targetstring | RefObject<HTMLElement | null>--CSS selector or React ref for the target element
titlestring--Step title shown in the tooltip header
contentReactNode--Step content -- string or React element
placement'top' | 'bottom' | 'left' | 'right' | 'auto''auto'Tooltip placement relative to target
spotlightPaddingnumber--Padding around the spotlight cutout (px)
spotlightRadiusnumber--Border radius of the spotlight cutout (px)
action{ label: string; onClick: () => void }--Optional CTA button inside the tooltip
when() => boolean | Promise<boolean>--Condition -- step is skipped if this returns false
onBeforeShow() => void | Promise<void>--Called before the step is shown (can be async)
onAfterShow() => void--Called after the step is visible
onHide() => void--Called when the step is hidden
disableOverlayClosebooleanfalsePrevent overlay click from dismissing
interactivebooleanfalseMake the spotlight hole genuinely transparent to all pointer/keyboard/focus events, so the user can interact with the real highlighted element (typing, hovering, dragging, scrolling)
advanceOn{ event: string; selector?: string }--Auto-advance the tour when event fires on the target (or a descendant matching selector). Implies interactive
routestring--The path this step lives on. When advancing to it on a different route, the provider calls navigate(route) and waits for the target there. Supports exact, :param, and trailing *
onBeforeStep() => void | Promise<void>--Escape hatch run before the step's target is resolved (and before route navigation). Awaited
timeoutnumber5000Max time (ms) to wait for target to appear in the DOM before skipping this step. Overrides waitForElementTimeout on the provider

SpotlightHighlightProps

Props for the <SpotlightHighlight> component for single-element highlights.

PropTypeDefaultDescription
targetstring | RefObject<HTMLElement | null>--CSS selector or React ref for the target element
titlestring--Tooltip title
contentReactNode--Tooltip content
activebooleantrueWhether the highlight is currently visible
placement'top' | 'bottom' | 'left' | 'right' | 'auto''auto'Tooltip placement relative to target
spotlightPaddingnumber--Padding around the spotlight cutout (px)
spotlightRadiusnumber--Border radius of the spotlight cutout (px)
onDismiss() => void--Called when the highlight is dismissed

useSpotlight()

Hook to access spotlight context. Must be used within a <SpotlightProvider>.

const spotlight = useSpotlight()

Return value: SpotlightContextValue

PropertyTypeDescription
start(tourId: string) => voidStart a tour by its ID
stop() => voidStop the currently active tour
next() => voidAdvance to the next step
previous() => voidGo back to the previous step
skip() => voidSkip the current tour
goToStep(index: number) => voidJump to a specific step by index
isActivebooleanWhether a tour or highlight is currently active
activeTourIdstring | nullID of the currently active tour, or null
currentStepnumberIndex of the current step (zero-based)
totalStepsnumberTotal number of steps in the active tour
registerTour(id, steps, callbacks?) => voidRegister a tour (used internally by SpotlightTour)
unregisterTour(id: string) => voidUnregister a tour (used internally)
highlight(step: SpotlightStep) => voidShow a single-element highlight
dismissHighlight() => voidDismiss the active highlight

useSpotlightControl()

A convenience hook that wraps useSpotlight() with memoized callbacks. Provides the same control methods without the internal registration methods.

const spotlight = useSpotlightControl()

Return value: SpotlightControl

PropertyTypeDescription
start(tourId: string) => voidStart a tour by its ID
stop() => voidStop the currently active tour
next() => voidAdvance to the next step
previous() => voidGo back to the previous step
skip() => voidSkip the current tour
goToStep(index: number) => voidJump to a specific step by index
highlight(step: SpotlightStep) => voidShow a single-element highlight
dismissHighlight() => voidDismiss the active highlight
isActivebooleanWhether a tour or highlight is currently active

useSpotlightTarget()

Hook that returns a RefObject to attach to a target element. Use this instead of CSS selectors when you want type-safe, refactor-friendly targets.

const ref = useSpotlightTarget<HTMLInputElement>()

// Use in steps:
{ target: ref, title: 'Search', content: '...' }

// Attach to element:
<input ref={ref} />

Return value

TypeDescription
RefObject<T | null>A React ref to attach to the target DOM element

SpotlightLabels

Labels for i18n. All properties are optional and fall back to English defaults.

PropertyTypeDefaultDescription
nextstring'Next'Next button label
previousstring'Previous'Previous button label
skipstring'Skip'Skip button label
donestring'Done'Done button label (last step)
closestring'Close'Close button aria-label
stepOf(current: number, total: number) => string'Step {n} of {m}'Step counter format function

TooltipRenderProps

Props passed to the renderTooltip function on <SpotlightTour>.

PropertyTypeDescription
stepSpotlightStepThe current step configuration
next() => voidAdvance to the next step or complete the tour
previous() => voidGo back to the previous step
skip() => voidSkip the tour
currentIndexnumberZero-based index of the current step
totalStepsnumberTotal number of steps

TourState

Persisted state for a tour, provided via the onStateChange callback.

PropertyTypeDescription
status'idle' | 'active' | 'completed'Current lifecycle status
currentStepIndexnumberIndex of the current step (when active)
seenStepsnumber[]Indices of steps the user has seen
completedAtnumber | undefinedTimestamp when the tour was completed
skippedAt{ stepIndex: number; timestamp: number } | undefinedStep index and timestamp when the tour was skipped

Headless core (react-tourlight/core)

The react-tourlight/core subpath exports the entire unstyled engine with no CSS, no default tooltip, and no Floating UI. See the Headless Core guide. Key exports:

ExportDescription
useTour(options)Headless controller hook. Returns { status, isActive, currentIndex, totalSteps, step, targetElement, rect, clipPath, isResolving, start, stop, next, previous, skip, goToStep }.
isRouteActive / getCurrentPathRouter-agnostic path matcher and current-pathname helper.
createMemoryStorageIn-memory SpotlightStorage adapter.
loadPersistedTours / savePersistedTour / clearPersistedTour / isPersistedStateFresh / resolveStoragePersistence helpers.
createFocusTrap / setInert / getStepAriaLabel / createKeyboardHandler / scrollIntoViewFocus & a11y utilities.

All of the engine primitives below (plus useTour, isRouteActive, getCurrentPath, and createMemoryStorage) are also re-exported from the main react-tourlight entry for convenience.

UseTourOptions

PropertyTypeDefaultDescription
stepsSpotlightStep[]--Steps to drive through
onComplete() => void--Called when the tour finishes
onSkip(stepIndex: number) => void--Called when the tour is skipped
onStateChange(state: TourState) => void--Called on every transition
initialStatePartial<TourState>--Seed state, e.g. from persistence
waitForElementTimeoutnumber5000Default wait for a step target
navigate(path: string) => void--Route-aware navigation
isRouteActive(route, pathname) => booleanbuilt-inCustom matcher
autoScrollbooleantrueScroll the target into view before showing

Engine primitives

Advanced/low-level exports for building a fully custom tour UI. Most consumers won't need these directly — SpotlightProvider and SpotlightTour use them internally.

ExportSignatureDescription
createTourStateMachine(options: TourStateMachineOptions) => TourStateMachineActionsClosure-based state machine driving step/lifecycle transitions (start, stop, next, previous, skip, goToStep, getState, subscribe). No UI or DOM access.
waitForElement(target: string, options?: WaitForElementOptions) => Promise<HTMLElement | null>Waits for a CSS selector to match an element in the DOM via MutationObserver. Resolves with the element, or null after options.timeout (default 5000ms) elapses.
resolveTarget(target: string | RefObject<HTMLElement | null>) => HTMLElement | nullResolves a step's target (CSS selector or ref) to a DOM element, or null if not found.
getTargetRect(element: HTMLElement) => ElementRectReturns an element's getBoundingClientRect() as a plain { x, y, width, height } object.
measureElement(element: HTMLElement, padding?: number) => ElementRectLike getTargetRect, but expands the rect by padding pixels on all sides.
generateClipPath(rect: ElementRect, padding: number, radius: number) => stringBuilds the clip-path: path(evenodd, ...) value used for the spotlight cutout around rect.

TourStateMachineOptions

PropertyTypeDescription
stepsSpotlightStep[]Steps to drive through
initialStatePartial<TourState>Optional initial state (e.g. to resume a persisted tour)
onComplete() => voidCalled when the tour finishes
onSkip(stepIndex: number) => voidCalled when the tour is skipped
onStateChange(state: TourState) => voidCalled on every state transition

WaitForElementOptions

PropertyTypeDefaultDescription
timeoutnumber5000Maximum time to wait, in milliseconds

SpotlightTheme

Full theme interface. See the Customization page for usage examples.

SectionProperties
overlaybackground: string
tooltipbackground: string, color: string, borderRadius: string, boxShadow: string, padding: string, maxWidth: string
titlefontSize: string, fontWeight: string, color: string, marginBottom: string
contentfontSize: string, color: string, lineHeight: string
buttonbackground: string, color: string, borderRadius: string, padding: string, fontSize: string, fontWeight: string, border: string, cursor: string, hoverBackground: string
buttonSecondarybackground: string, color: string, border: string, hoverBackground: string
progressbackground: string, fill: string, height: string, borderRadius: string
arrowfill: string
closeButtoncolor: string, hoverColor: string