Skip to content

Tour API reference

createGlowTour() returns a tour controller: the long-lived instance that creates workflows (via tour.create(), see the Builder reference), runs them, drives navigation, and exposes reactive state. One controller can be connected to one live root at a time.

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

Creates and returns a new tour controller instance.

Signature:

function createGlowTour(options?: GlowTourOptions): GlowTour

Parameters:

  • options.onSubscriberError - Called when a state/step subscriber throws an error (optional, no default)
  • options.onEvent - Monitoring callback for every tour this instance runs; see the Monitoring guide (optional, no default)

Returns: Tour controller instance

Usage:

const tour = createGlowTour({
onSubscriberError: (error) => {
console.error("Subscriber error:", error);
}
});

Starts building a new workflow on this controller. See the Builder reference for the full builder API.

Signature:

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

Runs a workflow built with .build(). Any previous run or navigation on this controller is cancelled first. The returned promise resolves once the first step is on screen, not when the tour ends, and rejects if that first step fails.

Signature:

start(workflow: WorkflowDefinition, options?: RunOptions): Promise<void>

Options:

  • startAt - Id of the step to start on, instead of the first one. Throws if no step carries that id. The workflow is not truncated: totalSteps is unchanged and previous() can go back before this step. See Resuming a tour.

Usage:

const workflow = tour.create("welcome").step({ id: "save-button", target: "#save-button", title: "Save", content: "Click here to save." }).build();
await tour.start(workflow);

Moves to the next step. Only available if canAdvance is true - check tour.state.get().canAdvance or the state a subscribe listener receives before calling it, or wire it to a button’s disabled prop.

Signature:

advance(): Promise<void>

Usage:

<button disabled={!state.canAdvance} onClick={() => tour.advance()}>
Next
</button>

Moves to the previous step. Only available if canPrevious is true.

Signature:

previous(): Promise<void>

Usage:

<button disabled={!state.canPrevious} onClick={() => tour.previous()}>
Previous
</button>

Goes to the step with this id, skipping the steps in between. The direction ("advance" or "previous") follows the position of that step. It does nothing while a transition is in progress or when that step is already shown, and it throws when no step has this id.

Steps are designated by id, like startAt in start(): an index would break as soon as steps are reordered or inserted.

Signature:

goTo(id: string): Promise<void>

Usage:

// Jump straight to the billing step
await tour.goTo("billing");

A step action or a target event handler can do the same with context.goTo(id), which also stops the remaining actions of its step, like context.advance().

Cancels the running tour. Does nothing when no tour is running. A disabled controls.cancel only blocks the tour UI: tour.cancel() still cancels.

Signature:

cancel(): Promise<void>

Usage:

<button onClick={() => tour.cancel()}>Skip tour</button>

Hide the popover of the running tour, and show it again. Both do nothing when no tour is running.

While the popover is hidden, the overlay, the indicator and the scroll lock stay on screen, and the tour keeps running: advance(), previous(), goTo() and cancel() still work. The popover has nothing left to trap focus in, so the page is no longer inert, focus moves from the popover to the target, and the keyboard shortcuts do nothing. It stays hidden across steps, until showPopover() or the end of the tour; a new start() shows it again.

showPopover() replays the popover’s entrance on the current step, makes the step modal again, and moves focus into the popover when the step auto focuses. state.popoverHidden reports which one is in effect.

Signature:

hidePopover(): void
showPopover(): void

Usage:

// Let the user look at the page without the popover, then bring it back
tour.hidePopover();
helpButton.addEventListener("click", () => tour.showPopover());

Cancels pending work and releases the connected root. The controller becomes unusable after this - create a new one with createGlowTour() if you need another tour.

Signature:

dispose(): void

Usage:

// e.g. in a framework's unmount/cleanup hook
tour.dispose();

Returns the current tour state as a plain snapshot (not reactive by itself - use subscribe below to react to changes).

Signature:

get(): TourState

Usage:

const { status, canAdvance } = tour.state.get();

Returns:

{
status: "idle" | "starting" | "transitioning" | "active" | "finished" | "cancelled" | "error" | "disposed"
awaitingTarget: boolean
popoverHidden: boolean
name: string
totalSteps: number
currentStepIndex: number
currentStep: TourCurrentStep | null
direction: "advance" | "previous"
canAdvance: boolean
canPrevious: boolean
canCancel: boolean
isFirstStep: boolean
isLastStep: boolean
error: Error | null
}

Subscribes to state changes. Called whenever any part of the state changes.

Signature:

subscribe(listener: (state: TourState) => void): () => void

Returns: Unsubscribe function

Usage:

const unsubscribe = tour.state.subscribe((state) => {
console.log("Tour status:", state.status);
if (state.status === "finished") {
unsubscribe();
}
});

Controller-related type exports for TypeScript users:

  • GlowTour - Tour controller interface
  • GlowTourOptions - Options for createGlowTour
  • TourEvent, TourEventListener, TourEventType, TourEventSource - The monitoring contract; see the Monitoring guide
  • TourState - Immutable state object returned by tour.state.get(). awaitingTarget is true while a navigation waits for the next step’s target to resolve - an async resolver, or the "wait" missing-target strategy - which is when the step being left is still on screen with its advance refused; see Behavior options. popoverHidden is true between hidePopover() and showPopover(), and false again whenever a tour starts or ends
  • TourCurrentStep - The active step’s target and props, part of TourState

TourStatus, TourEventType, and TourEventSource are unions that can gain members in a minor release. When you switch over them, keep a default branch.

See the Builder reference for tour.create()’s workflow/step-building API and every option’s default value.