Skip to content

Builder API reference

tour.create() returns a workflow builder: chain .step(), .do(), .wait(), and the other methods below to describe a tour, then call .build() to get an immutable WorkflowDefinition. For the controller that runs the resulting workflow (createGlowTour, tour.run, tour.advance, tour.state, …), see the Tour reference.

For framework-specific integration and components, see React, Vue, Solid, Angular, or Vanilla.

Starts building a new workflow.

Signature:

create(name: string, options?: StartOptions): WorkflowBuilder

Parameters:

  • name - Workflow identifier
  • options - Start options (see Start options)

Returns: Workflow builder for chaining

Usage:

const workflow = tour
.create("onboarding", {
cancellable: true,
onStart: () => console.log("Tour started"),
onFinish: () => console.log("Tour finished")
})
.step({ id: "step-1", /* ... */ })
.build();

Adds a step to the workflow.

Signature:

step(params: StepParameters): WorkflowStepBuilder

Parameters:

  • id - Stable identifier, unique within the workflow (required). Validated at .build() time. It is what run(workflow, { startAt }) uses to resume a tour, so prefer a name that survives reordering.
  • target - CSS selector, HTMLElement, or resolver function (required)
  • title - Step title displayed in popover (required)
  • content - Step description displayed in popover (required)
  • resetPropsOnEnter - Reset step props on enter (default true)
  • data - Optional record for custom step data
  • overlay - Overlay options (see Overlay options)
  • popover - Popover options (see Popover options)
  • indicator - Indicator options (see Indicator options)
  • behavior - Behavior options (see Behavior options)

Usage:

.step({
id: "feature",
target: "#feature",
title: "Meet the new feature",
content: "This will help you be more productive",
overlay: { opacity: 0.6 },
popover: { placementTryOrder: ["bottom", "top"] }
})

Executes a function between steps. Can be async. Returning false stops the rest of the step’s action sequence; any other value continues it.

Signature:

do(callback: StepAction<T>): WorkflowStepBuilder
type StepAction<T> = (
context: StepContext<T>,
) => Promise<boolean | void> | boolean | void

Usage:

.do(async () => {
// Wait for data to load
await fetchData();
})
.step({
id: "results",
target: "#results",
title: "Results loaded",
content: "Data is now available"
})

Pauses for a fixed duration.

Signature:

wait(ms: number): WorkflowStepBuilder

Usage:

.step({ id: "step-4", /* ... */ })
.wait(2000) // Wait 2 seconds
.step({ id: "step-5", /* ... */ })

Waits until a condition returns true.

Signature:

waitUntil(
fn: () => boolean,
options?: WaitUntilOptions
): WorkflowStepBuilder

Parameters:

  • fn - Condition function that returns true when ready
  • options - Wait options (see Wait options)

Usage:

.waitUntil(() => document.querySelector("#data") !== null, {
interval: 100,
timeout: 5000
})
.step({
id: "data",
target: "#data",
title: "Here's your data",
content: "The data has loaded"
})

Waits until an element enters the DOM.

Signature:

waitUntilElement(
selector: string,
options?: WaitUntilOptions
): WorkflowStepBuilder

Parameters:

  • selector - CSS selector to wait for
  • options - Wait options (see Wait options)

Usage:

.waitUntilElement("#modal", { timeout: 3000 })
.step({
id: "modal",
target: "#modal",
title: "Modal opened",
content: "The modal is now visible"
})

Listens for a DOM event on the current target during this step.

Signature:

// A known DOM event name, narrowed to its concrete event type.
onTargetEvent<TEventName extends EventName>(
event: TEventName,
callback: Callback<EventForName<TEventName>>
): WorkflowStepBuilder
// Several event names at once, sharing one callback.
onTargetEvent<TEventNames extends readonly EventName[]>(
events: TEventNames,
callback: Callback<EventForName<TEventNames[number]>>
): WorkflowStepBuilder
// A custom event name, with the event type supplied by you.
onTargetEvent<TEvent extends Event>(
event: string,
callback: Callback<TEvent>
): WorkflowStepBuilder
type Callback<TEvent> = (
event: TEvent,
context: StepEventContext<T>,
) => void | Promise<void>

Usage:

.step({
id: "form",
target: "#form",
title: "Submit the form",
content: "Click the submit button"
})
.onTargetEvent("submit", (event, context) => {
console.log("Form submitted!");
context.advance();
})

Finalizes and returns the immutable workflow definition.

Signature:

build(): WorkflowDefinition

Returns: Immutable workflow ready for execution

Usage:

const workflow = tour
.create("onboarding")
.step({
id: "welcome",
target: "#welcome",
title: "Welcome",
content: "Let's get started"
})
.build();

Step-level callback, passed as part of .step()’s params. Called before advancing to the next step. Can be async.

Signature:

beforeAdvance?(context: BeforeActionStepContext<T>): void | Promise<void>

Usage:

.step({
id: "button",
target: "#button",
title: "Step 1",
content: "Description",
beforeAdvance: async (context) => {
// Perform cleanup or validation
await saveFormData();
}
})

Step-level callback, passed as part of .step()’s params. Called before cancelling the tour. Can be async.

Signature:

beforeCancel?(context: BeforeActionStepContext<T>): void | Promise<void>

Step-level callback, passed as part of .step()’s params. Called before going to the previous step. Can be async.

Signature:

beforePrevious?(context: BeforeActionStepContext<T>): void | Promise<void>

Options passed to tour.create() to configure the initial workflow behavior.

Option Type Default Description
cancellable boolean true Whether the tour can be cancelled by the user
animated boolean true* Enable animations (auto-disabled if OS prefers reduced motion)
overlay OverlayOptions - Overlay appearance (see Overlay options)
popover PopoverOptions - Popover appearance (see Popover options)
indicator IndicatorOptions - Indicator appearance (see Indicator options)
behavior StepBehavior - Step behavior (see Behavior options)
allowScroll boolean true The page stays scrollable during the tour; set false to lock page scroll while the tour is active (restored on finish/cancel/error/dispose)
onStart (context: LifecycleHookContext) => void | Promise<void> - Called when the tour starts
onCancel (context: LifecycleHookContext) => void | Promise<void> - Called when the tour is cancelled
onFinish (context: LifecycleHookContext) => void | Promise<void> - Called when the tour completes
onEvent (event: TourEvent) => void - Monitoring callback for this workflow. Cannot abort a transition; see the Monitoring guide

*Animations automatically disable when the browser detects prefers-reduced-motion.

Control the semi-transparent overlay that darkens non-target areas.

Option Type Default Description
color string - Overlay color (uses theme’s overlay fill if not set)
opacity number 0.7 Overlay opacity (0 = transparent, 1 = opaque)
padding number 8 Padding around the target element (in pixels)
radius number 8 Border radius of the overlay cutout (in pixels)
animated boolean true Enable/disable animation
animation AnimationOptions - Custom animation (duration and easing)

Usage:

overlay: {
color: "rgba(0, 0, 0, 0.5)",
opacity: 0.6,
padding: 20,
radius: 8,
animated: true
}

Control the information box that displays step title and content.

Option Type Default Description
placementTryOrder Array ["bottom", "top", "right", "left"] Preferred placements in order of preference
gap number 16 Spacing between popover and target, and the minimum margin it keeps from the viewport edges (in pixels)
hideFooter boolean false Hide the footer with navigation buttons
hideAdvanceButton boolean false Hide the “Next” button (keyboard still works)
disableAdvanceButton boolean false Disable advancing (keyboard and button blocked)
hidePreviousButton boolean false Hide the “Previous” button (keyboard still works)
disablePreviousButton boolean false Disable going back (keyboard and button blocked)
animated boolean true Enable/disable animation
animation AnimationOptions - Custom animation (duration and easing)
keyboardShortcuts.advance Array ["Enter", "ArrowRight"] Keys to advance to next step
keyboardShortcuts.previous Array ["ArrowLeft", "Backspace"] Keys to go to previous step
keyboardShortcuts.cancel Array ["Escape"] Keys to cancel the tour
arrow PopoverArrowOptions - Arrow/pointer styling (see Arrow options)

Usage:

popover: {
placementTryOrder: ["right", "bottom", "left", "top"],
gap: 20,
hideFooter: false,
keyboardShortcuts: {
advance: ["Enter", "Space"],
previous: ["Backspace"],
cancel: ["Escape"]
}
}

Customize the arrow that points from the popover to the target element.

Option Type Default Description
disabled boolean false Hide the arrow
color string - Arrow color (uses theme’s surface color if not set)
size number 12 Arrow dimensions (in pixels)
borderWidth number 1 Arrow border width (in pixels)
borderRadius number 0 Arrow border radius (in pixels)
edgePadding number 16 Spacing from popover edges (in pixels)
styleNonce string - CSP nonce for injected arrow styles
disableAutoStyles boolean false Skip injecting built-in arrow styles (provide your own CSS)

Usage:

popover: {
arrow: {
size: 16,
color: "#ffffff",
borderWidth: 2,
edgePadding: 20
}
}

These options are written as inline custom properties on the popover, so they take precedence over the same --glow-tour-arrow-* variables set in your stylesheet. Pick one channel per property - see the Theming guide.

Control the decorative indicator/pointer that highlights the target element.

Option Type Default Description
disabled boolean false Hide the indicator
gap number 16 Spacing between indicator and target (in pixels)
placementTryOrder Array ["left", "right", "top", "bottom"] Preferred placements in order of preference
animated boolean true Enable/disable animation
animation AnimationOptions - Custom animation (duration and easing)

Usage:

indicator: {
gap: 20,
placementTryOrder: ["top", "bottom", "left", "right"],
disabled: false
}

Control step interaction and scrolling behavior.

Option Type Default Description
allowInteraction boolean false Allow clicking/interacting with the target element
disableAutoFocus boolean false Skip auto-focusing the target element
disableAutoScroll boolean false Skip auto-scrolling to the target
missingTargetStrategy "error" | "wait" | "skip" "error" What to do if target isn’t found - see Handling errors
overlayClick "none" | "advance" | "cancel" "none" Action when clicking the dimmed overlay (outside the target)
targetTimeout number 3000 Time to wait for target (in milliseconds)
scroll ScrollOptions - Scroll behavior (see Scroll options)

Usage:

behavior: {
allowInteraction: true,
disableAutoFocus: false,
missingTargetStrategy: "skip",
targetTimeout: 5000,
scroll: {
behavior: "smooth",
block: "center",
inline: "nearest"
}
}

When a target disappears mid-step: if a step’s target is removed from the DOM while its step is on screen (a framework remounting it, for example), the presentation freezes in place for a short, fixed grace period instead of disappearing immediately - overlay, popover and pointer hold their last position, and interaction with the underlying page stays blocked even if allowInteraction is true. If the target reconnects within that window, the tour resumes on it with a smooth reposition and no re-entrance animation. If it doesn’t, missingTargetStrategy takes over exactly as it does for a target that was never found: error fails the tour, skip moves on, and wait keeps the presentation frozen for the rest of its budget - the grace period counts against targetTimeout rather than adding to it. The tour stays active throughout, so the popover’s own buttons keep working and remain the way out of a target that never comes back. This freeze isn’t configurable; it’s a presentation detail of the recovery, not a policy choice.

The onStart, onCancel, and onFinish callbacks receive a LifecycleHookContext object:

Property Type Description
step TourCurrentStep | null The step associated with this transition (see JSDoc for per-hook semantics)
abort() function Call synchronously (or before the hook’s promise resolves) to prevent the transition

Transition semantics:

  • onStart: step is the first step about to be entered, or null if the workflow has no steps. Calling abort() prevents the tour from starting.
  • onCancel: step is always the current step (never null at cancellation time). Calling abort() prevents cancellation and keeps the tour active.
  • onFinish: step is the last step the tour was on, or null only for zero-step workflows. Calling abort() prevents completion and keeps the tour in its current state.

Usage (example: confirm before cancelling):

onCancel: (context) => {
if (!window.confirm("Are you sure you want to exit the tour?")) {
context.abort();
}
}

Control how the browser scrolls to the target element. A step scrolls only when part of its target falls outside the viewport; disableAutoScroll opts out entirely.

The step does not wait for the scroll to finish before appearing. The spotlight shows up straight away and tracks the target as the page travels; the popover and the pointer enter once the page has come to rest, so they are never placed against a rect that is still moving.

Option Type Default Description
behavior "auto" | "smooth" "smooth"* Scroll animation style
block "start" | "center" | "end" | "nearest" "center" Vertical alignment within viewport
inline "start" | "center" | "end" | "nearest" "nearest" Horizontal alignment within viewport

*Automatically switches to "instant" when the browser detects prefers-reduced-motion.

Usage:

scroll: {
behavior: "smooth",
block: "center",
inline: "nearest"
}

Control animation timing.

Option Type Default Description
duration number 180 Animation duration (in milliseconds)
easing string "ease-out" CSS easing function

Usage:

animation: {
duration: 300,
easing: "cubic-bezier(0.25, 0.46, 0.45, 0.94)"
}

When animated is false or reduced motion is detected, animations disable and duration collapses to 0.

Options for .waitUntil() and .waitUntilElement().

Option Type Default Description
interval number 16 How often to check condition (in milliseconds)
timeout number 3000 Maximum wait time (in milliseconds)

Usage:

.waitUntil(() => dataLoaded, {
interval: 100,
timeout: 10000
})

Builder-related type exports for TypeScript users:

  • WorkflowBuilder - Workflow builder interface
  • WorkflowStepBuilder - Step builder interface (chained after .step())
  • WorkflowDefinition - Immutable compiled workflow
  • StepParameters - Parameters for .step()
  • StartOptions - Options for tour.create()
  • LifecycleHookContext - Context passed to onStart, onCancel, onFinish callbacks
  • StepBehavior - Behavior options
  • OverlayOptions - Overlay options
  • PopoverOptions - Popover options
  • PopoverArrowOptions - Arrow options
  • IndicatorOptions - Indicator options
  • ScrollOptions - Scroll options
  • AnimationOptions - Animation options
  • WaitUntilOptions - Wait options
  • StepContext - Context passed to step callbacks
  • TargetResolver - Target resolution function type

See the Tour reference for the controller API that runs a built workflow.