Types

All types are exported from both @trailguide/core and @trailguide/runtime.

import type {
  Trail, Step, Placement, TrailMode, StepType,
  StepAction, StepAssert, StepWait,
  CelebrationConfig, FeedbackConfig,
  TrailguideOptions, AnalyticsConfig
} from '@trailguide/core'

Trail

A complete tour definition.

interface Trail {
  id: string          // unique identifier used in analytics and tourStorage
  title: string       // display name used in analytics
  version: string     // semver string, bump when steps change significantly
  steps: Step[]       // ordered list of steps
  mode?: TrailMode    // 'tour' (default), 'test', or 'both'
}

Step

A single step in a tour.

interface Step {
  id: string            // unique within the tour; used in analytics
  target: string        // CSS selector for the element to highlight
  placement: Placement  // which side of the target to show the tooltip
  title: string         // tooltip heading
  content: string       // tooltip body text
  optional?: boolean    // if true, silently skip if target is not found/visible
  url?: string          // pathname this step belongs to, used for cross-page tours
 
  // Step type (default: 'element' — standard tooltip)
  stepType?: StepType
 
  // Celebration overlay config (used when stepType is 'celebration')
  celebration?: CelebrationConfig
 
  // Feedback form config (used when stepType is 'feedback')
  feedback?: FeedbackConfig
 
  // Playwright test fields
  action?: StepAction        // action to execute on the target
  value?: string             // value for fill, select, scroll, dragTo, etc.
  assert?: StepAssert        // assertion to run after the action
  wait?: StepWait            // condition to wait for before the assertion
  opensNewTab?: boolean      // if true, waits for a new tab to open after the action
  tabContext?: 'main' | 'new' // switch active page context before this step
}

Placement

type Placement = 'top' | 'bottom' | 'left' | 'right'

Trailguide uses @floating-ui/dom under the hood. The tooltip will flip to the opposite side and shift to stay in viewport automatically.


TrailMode

type TrailMode = 'tour' | 'test' | 'both'

Controls how a trail runs. 'tour' shows onboarding tooltips to users (the default). 'test' runs the trail as a Playwright test only. 'both' does both from the same JSON file. See the Playwright guide for setup.


StepType

type StepType = 'element' | 'celebration' | 'feedback'

Controls how a step is rendered.

  • 'element' (default): standard tooltip anchored to a DOM element
  • 'celebration': fullscreen overlay with confetti and a completion message
  • 'feedback': fullscreen rating form (stars, thumbs, or NPS) with an optional comment field

CelebrationConfig

Configuration for a celebration step.

interface CelebrationConfig {
  emoji?: string        // emoji displayed above the title (default: '🎉')
  showConfetti?: boolean // animate confetti particles (default: true)
  ctaLabel?: string     // button label (default: 'Done')
}

FeedbackConfig

Configuration for a feedback step.

interface FeedbackConfig {
  type: 'stars' | 'thumbs' | 'nps'   // rating widget type
  question?: string                    // prompt shown above the widget
  allowComment?: boolean               // show an optional comment textarea
  commentPlaceholder?: string          // placeholder text for the textarea
  webhook?: string                     // POST rating + comment to this URL on submit
  ctaLabel?: string                    // submit button label (default: 'Submit')
}

When webhook is set, runTrail POSTs a JSON body of { rating, comment, stepId, trailId } to that URL on submission.


StepAction

type StepAction =
  | 'click'         // locator.click()
  | 'rightClick'    // locator.click({ button: 'right' })
  | 'dblclick'      // locator.dblclick()
  | 'hover'         // locator.hover()
  | 'focus'         // locator.focus()
  | 'fill'          // locator.fill(value)
  | 'type'          // locator.pressSequentially(value)
  | 'press'         // locator.press(value), e.g. "Enter", "Control+s"
  | 'select'        // locator.selectOption(value)
  | 'check'         // locator.check()
  | 'uncheck'       // locator.uncheck()
  | 'scroll'        // page.evaluate / el.scrollBy — value is "deltaX,deltaY"
  | 'dragTo'        // locator.dragTo(page.locator(value))
  | 'setInputFiles' // locator.setInputFiles(value)
  | 'goto'          // page.goto(value)
  | 'evaluate'      // page.evaluate(value) — runs arbitrary JS

See the Playwright guide for the full action reference with examples.


StepAssert

interface StepAssert {
  type:
    | 'visible'       // element is visible
    | 'hidden'        // element is hidden
    | 'enabled'       // element is not disabled
    | 'disabled'      // element is disabled
    | 'checked'       // checkbox or radio is checked
    | 'empty'         // input or element has no content
    | 'text'          // element text matches expected exactly
    | 'containsText'  // element text contains expected
    | 'value'         // input value matches expected
    | 'hasClass'      // element has the CSS class in expected
    | 'attribute'     // element attribute equals expected
    | 'count'         // number of matching elements equals expected
    | 'url'           // page URL matches expected
    | 'title'         // page title matches expected
    | 'screenshot'    // visual screenshot comparison
    | 'custom'        // run expected as a JS expression
  expected?: string   // value for text/value/url/title/hasClass/count/containsText/custom
  attribute?: string  // attribute name when type is 'attribute'
}

StepWait

An optional wait condition that runs after the action and before the assertion.

interface StepWait {
  type: 'networkIdle' | 'load' | 'domcontentloaded' | 'selector' | 'timeout'
  value?: string  // selector (for 'selector') or milliseconds (for 'timeout')
}

TrailguideOptions

Options passed to new Trailguide(options) or the static start() function.

interface TrailguideOptions {
  onComplete?: () => void
  onSkip?: () => void
  /** Fires when stop() is called while the tour is active */
  onAbandoned?: () => void
  onStepChange?: (step: Step, index: number) => void
  /** Fires when a step's target cannot be found or is not visible */
  onError?: (step: Step, error: 'element_not_found' | 'element_not_visible') => void
  analytics?: AnalyticsConfig
}

AnalyticsConfig

Configuration for Trailguide Pro analytics.

interface AnalyticsConfig {
  /** Analytics ingestion endpoint — use https://app.gettrailguide.com/api/analytics */
  endpoint: string
  /** Your Trailguide user ID from app.gettrailguide.com */
  userId: string
  /** Override trail.id for analytics (useful when merging metrics across tour versions) */
  trailId?: string
  /** Log analytics events to the browser console */
  debug?: boolean
}

UseTrailManagerOptions

Options for useTrailManager and useRegisterTour.

interface UseTrailManagerOptions {
  once?: boolean
  storageKey?: string
  enabled?: boolean
  delay?: number
  resumable?: boolean
  onComplete?: () => void
  onSkip?: () => void
  onAbandoned?: () => void
  onStepChange?: (step: Step, index: number) => void
  onError?: (step: Step, error: 'element_not_found' | 'element_not_visible') => void
  analytics?: AnalyticsConfig
}

UseTrailManagerReturn

Return value of useTrailManager and useRegisterTour.

interface UseTrailManagerReturn {
  isActive: boolean
  currentStep: Step | null
  currentStepIndex: number
  totalSteps: number
  show: () => void
  dismiss: () => void
  reset: () => void
  next: () => void
  prev: () => void
  skip: () => void
  goToStep: (index: number) => void
}