npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@stepbeam/sdk

v0.1.1

Published

Customer-facing SDK for rendering product guides and NPS surveys

Readme

StepBeam SDK

The customer-facing JavaScript SDK for rendering interactive product guides and NPS surveys.

Links: Homepage · Admin & sign-up · Issues

Features

  • Multiple Step Types: Support for modal, tooltip, and hotspot guides
  • Smart Triggers: Automatically show guides based on page load or element visibility
  • Multi-Language Support: Built-in i18n with auto-detection, RTL support, and 12+ languages
  • NPS Surveys: Display and collect Net Promoter Score surveys
  • Customizable Styling: Pre-built styles with full customization options
  • Event Callbacks: Track user progress through guides
  • Lightweight: No external dependencies
  • TypeScript Support: Full type definitions included

Installation

Option 1: NPM Package

npm install @stepbeam/sdk

Option 2: Script Tag (recommended for quick setup)

Drop a single async-loader snippet into your site's <head>. The SDK loads non-blocking and queues any calls made before it's ready, so you can call StepBeam('init', ...) immediately after the loader without waiting for a callback:

<!-- StepBeam SDK -->
<script>
(function(p,r,o,d,u,c,t){
  p[u]=p[u]||function(){(p[u]._q=p[u]._q||[]).push(arguments)};
  p[u]._q=p[u]._q||[];p[u]._appKey=d;p[u]._cdnUrl=o;
  c=r.createElement('script');c.async=1;c.src=o+'/stepbeam.min.js';
  c.setAttribute('data-app-key',d);
  t=r.getElementsByTagName('script')[0];t.parentNode.insertBefore(c,t);
})(window,document,'https://sdk.stepbeam.com','YOUR_APP_KEY','StepBeam');

StepBeam('init', {
  appKey: 'YOUR_APP_KEY',
  apiUrl: 'https://api.stepbeam.com',
});
</script>

Replace YOUR_APP_KEY with the app key from your StepBeam admin (https://admin.stepbeam.com/admin/settings/applications). The admin's Onboarding Setup page also generates a per-application snippet you can copy directly.

The SDK bundle:

  • Loads asynchronously — no impact on page load
  • Is served from https://sdk.stepbeam.com/stepbeam.min.js
  • Self-installs as window.StepBeam
  • Contains all SDK functionality in a single ~181 KB minified bundle

Quick Start

SDK Initialization

Before using any SDK functionality, you must initialize the SDK with your API key and API URL:

import { init, getSiteId, isInitialized, getConfig } from '@stepbeam/sdk';

// Initialize the SDK with your API key and API URL (both required)
await init('pk_live_your_api_key_here', {
  apiUrl: 'https://api.stepbeam.com'  // Required!
});

// For local development:
await init('pk_live_your_api_key_here', {
  apiUrl: 'http://localhost:3011'
});

// Check initialization status
console.log(isInitialized()); // true

// Retrieve the site ID (returned from authentication)
console.log(getSiteId()); // 'site_abc123'

// Get full configuration
const config = getConfig();
console.log(config.accountName); // Your account name
console.log(config.apiUrl);      // API endpoint

Important Notes:

  • init() is async and authenticates with the StepBeam backend
  • init() must be called before using any other SDK functions
  • init() can only be called once per session
  • Calling init() twice throws SDKAlreadyInitializedError
  • Calling SDK functions before init() throws SDKNotInitializedError
  • Invalid API keys throw SDKAuthenticationError

Using StepBeam

import { init, StepBeam, getApiUrl } from '@stepbeam/sdk';

// First, initialize the SDK with your API key
await init('pk_live_your_api_key_here');

// Then create a StepBeam instance
const guide = new StepBeam({
  apiUrl: getApiUrl(), // Use the authenticated API URL
  applicationId: 'your-app-id',
  appKey: 'your-app-key',
  userId: 'user-123',  // Required: identifies the guide viewer
  userProperties: {    // Optional: enrich events with user context
    plan: 'pro',
    country: 'US',
    role: 'admin',
  },
  onStepComplete: (step) => {
    console.log('Step completed:', step.title);
  },
  onGuideComplete: (guide) => {
    console.log('Guide completed:', guide.title);
  },
  onGuideClose: () => {
    console.log('Guide closed');
  }
});

// Load and start a guide
async function startGuide() {
  await guide.loadGuide('guide-id');
  guide.start();
}

startGuide();

Package Structure

The SDK follows a modular architecture for maintainability and scalability:

sdk/
├── src/
│   ├── core/                    # Core SDK functionality
│   │   └── index.ts             # Core module entry point
│   │   # Future: StepBeam, EventQueue, types
│   │
│   ├── modules/                 # Feature modules
│   │   ├── index.ts             # Modules barrel export
│   │   ├── guides/              # Product guides module
│   │   │   └── index.ts         # Guides entry point
│   │   │   # Future: TriggerManager, GuideRenderer, TooltipRenderer,
│   │   │   #         ModalRenderer, HotspotRenderer
│   │   │
│   │   └── nps/                 # NPS surveys module
│   │       └── index.ts         # NPS entry point
│   │       # Future: NPSTriggerManager, NPSSurveyRenderer,
│   │       #         SurveyFrequencyManager
│   │
│   ├── utils/                   # Shared utilities
│   │   └── index.ts             # Utils entry point
│   │   # Future: i18n, TranslationManager, SelectorResolver,
│   │   #         selectorUtils, styles
│   │
│   └── index.ts                 # Main SDK entry point
│
├── dist/                        # Built output
├── examples/                    # Usage examples
├── package.json
├── tsconfig.json
└── README.md

Module Responsibilities

| Module | Purpose | |--------|---------| | core | Main SDK orchestration, event queuing, core types | | modules/guides | Product tour rendering and trigger management | | modules/nps | NPS survey rendering and frequency control | | utils | i18n, selectors, styling, and shared helpers |

Import Patterns

// Main entry point (recommended)
import { StepBeam } from '@stepbeam/sdk';

// Direct module imports (for tree-shaking)
import { GuideRenderer } from '@stepbeam/sdk/modules/guides';
import { NPSSurveyRenderer } from '@stepbeam/sdk/modules/nps';
import { detectBrowserLanguage } from '@stepbeam/sdk/utils';

SDK Initialization API

The SDK must be initialized with an API key before any other functions can be used. Initialization authenticates with the StepBeam backend and retrieves your account configuration.

init(apiKey: string, options?: SDKInitOptions): Promise<void>

Initialize the SDK with your API key. This function is async and authenticates with the backend.

import { init } from '@stepbeam/sdk';

// Basic initialization
await init('pk_live_your_api_key_here');

// With options (apiUrl is REQUIRED)
await init('pk_live_your_api_key_here', {
  apiUrl: 'https://api.stepbeam.com',  // Required!
  debug: true,
});

// For local development:
await init('pk_live_your_api_key_here', {
  apiUrl: 'http://localhost:3011',
  debug: true,
});

Parameters:

  • apiKey (string): Your unique API key from the StepBeam dashboard. Must be at least 16 characters.
  • options (SDKInitOptions): Configuration options:
    • apiUrl (string, required): Your StepBeam API endpoint URL. Must be a valid HTTP/HTTPS URL. There is no default value - this prevents accidental deployments to production with localhost URLs.
    • debug (boolean): Enable debug logging (default: false)

⚠️ Breaking Change (v1.1): The apiUrl option is now required. Previously, the SDK defaulted to http://localhost:3011, which caused issues when deploying to production. You must now explicitly provide your API URL.

Throws:

  • SDKInitializationError: If the apiKey is invalid (empty, too short, etc.)
  • SDKAuthenticationError: If authentication with the backend fails
  • SDKAlreadyInitializedError: If init() has already been called

getSiteId(): string

Get the site ID returned from authentication.

import { init, getSiteId } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here');
const siteId = getSiteId(); // 'site_abc123'

Throws:

  • SDKNotInitializedError: If init() has not been called

getApiKey(): string

Get the API key used for initialization.

import { init, getApiKey } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here');
const apiKey = getApiKey();

getAccountName(): string

Get the account name associated with your API key.

import { init, getAccountName } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here');
const accountName = getAccountName(); // 'Your Company'

getApiUrl(): string

Get the configured API URL.

import { init, getApiUrl } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here');
const apiUrl = getApiUrl(); // 'https://api.stepbeam.com'

getConfig(): object

Get the full SDK configuration.

import { init, getConfig } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here', { debug: true });
const config = getConfig();
// {
//   siteId: 'site_abc123',
//   apiUrl: 'https://api.stepbeam.com',
//   debug: true,
//   accountName: 'Your Company',
//   authenticatedAt: '2024-01-15T10:30:00.000Z'
// }

isInitialized(): boolean

Check if the SDK has been initialized.

import { init, isInitialized } from '@stepbeam/sdk';

console.log(isInitialized()); // false
await init('pk_live_your_api_key_here');
console.log(isInitialized()); // true

isInitializing(): boolean

Check if SDK initialization is currently in progress.

import { isInitializing } from '@stepbeam/sdk';

console.log(isInitializing()); // true (during init)

Error Classes

The SDK provides specific error classes for initialization issues:

import {
  init,
  SDKInitializationError,
  SDKAuthenticationError,
  SDKNotInitializedError,
  SDKAlreadyInitializedError,
} from '@stepbeam/sdk';

try {
  await init('your-api-key');
} catch (error) {
  if (error instanceof SDKInitializationError) {
    console.error('Invalid API key format:', error.message);
  } else if (error instanceof SDKAuthenticationError) {
    console.error('Authentication failed:', error.message);
  } else if (error instanceof SDKAlreadyInitializedError) {
    console.error('SDK already initialized');
  }
}

| Error Class | When Thrown | |-------------|-------------| | SDKInitializationError | Invalid apiKey (empty, too short) | | SDKAuthenticationError | Authentication with backend failed | | SDKAlreadyInitializedError | init() called more than once | | SDKNotInitializedError | SDK function called before init() |

Debug Logging and Error Handling

Enable verbose logging during development to diagnose initialization and runtime issues:

import { init } from '@stepbeam/sdk';

await init('pk_live_your_api_key_here', {
  apiUrl: 'https://api.stepbeam.com',
  debug: true,
});

Or via the script-tag global:

StepBeam('init', {
  appKey: 'YOUR_APP_KEY',
  apiUrl: 'https://api.stepbeam.com',
  debug: true,
});

Network failures (event delivery, guide fetches) are retried automatically with exponential backoff. The retry behavior is internal and not exposed as a public configuration option — if you need custom error reporting, wrap your own initialization or track() calls in a try/catch and forward to your monitoring service.

NPS Surveys

NPS surveys are configured in the StepBeam admin (Surveys → Create NPS) with their own targeting rules — segment, page URL, frequency, cooldown — and auto-render in the SDK whenever the targeting matches and the visitor is eligible per the configured cooldown.

For most customers, no SDK code is needed beyond the standard install: as soon as init() succeeds and the visitor is identified, eligible NPS surveys are fetched and shown automatically.

For advanced use cases (rendering an NPS widget at a specific moment in your app), import the NPSSurveyRenderer class directly:

import { NPSSurveyRenderer } from '@stepbeam/sdk';

const renderer = new NPSSurveyRenderer({
  // theme, callbacks, etc.
});

renderer.render(survey); // survey is the NPSSurvey object from the API

The auto-rendered widget shows the survey title and question, a 0-10 rating scale, an optional description and comment field, and a close button. Submission auto-dismisses the widget and posts the response to the StepBeam backend.

Custom Event Tracking

The SDK lets you send arbitrary analytics events to the backend alongside the built-in guide lifecycle events (guide_started, step_completed, etc.). This is useful for tracking feature usage, button clicks, and any other in-app behaviour you want to correlate with guide engagement.

TypeScript SDK (StepBeam class)

import { StepBeam } from '@stepbeam/sdk';

const guide = new StepBeam({ apiUrl: 'https://api.stepbeam.com' });

// 1. Simple event – just a name
const result = await guide.trackCustomEvent('button_click');

// 2. Event with metadata properties
const result = await guide.trackCustomEvent('feature_used', {
  featureName: 'quick_actions',
  page: '/settings',
});

// 3. Event with explicit context (guide, step, session, user)
const result = await guide.trackCustomEvent(
  'onboarding_step_skipped',
  { reason: 'already_familiar' },
  {
    guideId: 42,
    stepId: 3,
    sessionId: 'sess_abc123',
    userId: 'usr_xyz789',
  }
);

// 4. Check the result
if (!result.ok) {
  console.error('Tracking failed:', result.error);
}

Browser snippet (StepBeam global)

When the SDK is loaded via the script-tag installer (Option 2), the same custom-event API is available through the global StepBeam(command, ...) dispatcher:

// Simple
StepBeam('trackCustomEvent', 'button_click', { buttonId: 'signup' });

// With context and callback
StepBeam(
  'trackCustomEvent',
  'feature_used',
  { featureName: 'export_csv' },
  { guideId: 5, userId: 'usr_abc' },
  function (err, event) {
    if (err) console.error(err);
    else console.log('Tracked:', event);
  }
);

Calls made before the SDK finishes loading are queued by the async loader and replayed automatically once it's ready, so you don't need to wait for a "loaded" event before tracking.

Event Name Rules

| Rule | Example | |---|---| | Must start with a letter | ✅ button_click1click | | Only letters, digits, underscores | ✅ featureUsedmy-event | | No spaces or special characters | ❌ my eventcom.click |

Metadata Size Limit

The properties object is serialised to JSON before sending. The total serialised size must not exceed 10 KB. Payloads larger than 10 KB are rejected client-side before any network request is made.

How It Works Under the Hood

  1. The SDK validates the event name and serialised properties size.
  2. A POST /events request is sent with type: "custom". The event name is placed in metadata.customEventName; all extra properties are merged into metadata.
  3. The backend persists the event and fires any configured webhooks.
  4. The event appears in the real-time event stream (GET /events/stream) and is queryable via GET /events?type=custom.

Static Validation Helpers

Both validation steps are exposed as static methods for use outside of a StepBeam instance:

import { StepBeam } from '@stepbeam/sdk';

StepBeam.validateEventName('button_click');
// → { valid: true }

StepBeam.validateEventName('123bad');
// → { valid: false, error: '...' }

StepBeam.validateEventProperties({ page: '/home' });
// → { valid: true, serialized: '{"page":"/home"}' }

Guide Triggers

Guides can be configured to start automatically based on different trigger conditions. This is particularly useful for contextual onboarding and just-in-time help.

Page Load Trigger

Automatically start a guide when the page loads, with an optional delay:

{
  trigger: {
    type: 'page_load',
    delay: 2000 // milliseconds (optional, defaults to 0)
  }
}

Use cases:

  • Welcome tours for new users
  • Feature announcements
  • General onboarding flows

Element Visible Trigger

Start a guide when a specific element becomes visible in the viewport:

{
  trigger: {
    type: 'element_visible',
    selector: '#dashboard-widget',
    threshold: 0.5 // percentage visible (optional, defaults to 0.5)
  }
}

Use cases:

  • Contextual help for specific features
  • Progressive disclosure of functionality
  • Feature discovery as users scroll

URL Change Trigger (SPA Support)

Automatically start a guide when the URL matches a specific pattern. Perfect for Single Page Applications (SPAs) built with React, Vue, Angular, etc.

{
  trigger: {
    type: 'url_change',
    urlPattern: '/dashboard*', // Wildcard pattern
    triggerOnInit: true // Check on page load (optional, defaults to true)
  }
}

URL Pattern Formats:

  • Wildcard: Use * for any characters (e.g., */products/*, *dashboard*)
  • Regex: Use /pattern/flags format (e.g., /\/product\/\d+/, /.*\/settings$/i)

Examples:

// Trigger on any dashboard page
{ type: 'url_change', urlPattern: '*/dashboard*' }

// Trigger on specific product pages using regex
{ type: 'url_change', urlPattern: '/\\/products\\/\\d+/' }

// Trigger on hash changes
{ type: 'url_change', urlPattern: '*#onboarding*' }

// Don't trigger on initial load, only on navigation
{ type: 'url_change', urlPattern: '*/settings*', triggerOnInit: false }

Use cases:

  • Page-specific onboarding in SPAs
  • Feature tours when users navigate to specific sections
  • Context-aware help that appears on relevant pages
  • Progressive onboarding across multiple SPA routes

Supported Navigation Events:

  • pushState (React Router, Vue Router navigation)
  • replaceState (programmatic URL updates)
  • popstate (browser back/forward buttons)
  • hashchange (hash-based routing)

Manual Trigger

Require explicit .start() call (default behavior):

{
  trigger: {
    type: 'manual'
  }
}

Use cases:

  • User-initiated help
  • Help menu items
  • Custom trigger logic

Disabling Auto-Start

You can load a guide without auto-starting, even if it has a trigger:

await guide.loadGuide('guide-id', false); // autoStart = false
// Guide is loaded but won't start automatically
guide.start(); // Start manually when ready

Step Types

Modal Steps

Full-screen modal dialogs that overlay the page content.

{
  type: 'modal',
  title: 'Welcome!',
  content: 'Get started with our product',
  config: {
    showOverlay: true,
    overlayColor: '#000000',
    overlayOpacity: 0.5,
    primaryButtonText: 'Next',
    secondaryButtonText: 'Back',
    showCloseButton: true,
    position: 'center', // 'center' | 'top' | 'bottom'
    width: 'medium' // 'small' | 'medium' | 'large'
  }
}

Tooltip Steps

Context-aware tooltips that point to specific elements on the page.

{
  type: 'tooltip',
  title: 'Feature Name',
  content: 'This is how you use this feature',
  selector: '#feature-button',
  config: {
    placement: 'top', // 'top' | 'bottom' | 'left' | 'right'
    showArrow: true,
    highlightElement: true,
    primaryButtonText: 'Next',
    secondaryButtonText: 'Back'
  }
}

Hotspot Steps

Interactive hotspots that users can click to reveal more information.

{
  type: 'hotspot',
  title: 'New Feature',
  content: 'Click to learn more about this feature',
  selector: '#new-feature',
  config: {
    pulse: true,
    color: '#007bff',
    size: 'medium' // 'small' | 'medium' | 'large'
  }
}

Multi-Language Support

The SDK includes comprehensive internationalization (i18n) support for creating guides in multiple languages with automatic language detection and RTL layout support.

Features

  • Automatic Language Detection: Detects user's preferred language from browser settings
  • Manual Language Control: Set and change language programmatically
  • RTL Layout Support: Automatic right-to-left layout for Arabic and Hebrew
  • Translation Fallbacks: Gracefully falls back to default language when translations are missing
  • Per-Step Translations: Translate titles, content, and button texts independently

Basic Usage

const guide = new StepBeam({
  apiUrl: 'https://api.stepbeam.com',
  preferredLanguage: 'es',         // Optional: Set preferred language
  autoDetectLanguage: true,        // Optional: Auto-detect from browser (default: true)
  onLanguageChange: (language) => {
    console.log('Language changed to:', language);
  }
});

// Load guide with translations
await guide.loadGuide('welcome-tour-multilingual');
guide.start();

Changing Language

// Get current language
const currentLanguage = guide.getCurrentLanguage(); // e.g., 'en'

// Change language
guide.setLanguage('es'); // Switches to Spanish and re-renders current step

// Get available languages for current guide
const languages = guide.getAvailableLanguages(); // e.g., ['en', 'es', 'fr', 'de']

Translation Structure

Guide-Level Translations

Define translations for your guide's title and description:

{
  "id": "welcome-tour",
  "title": "Welcome Tour",
  "description": "Learn how to use our product",
  "defaultLanguage": "en",
  "availableLanguages": ["en", "es", "fr", "de"],
  "translations": [
    {
      "language": "es",
      "title": "Tour de Bienvenida",
      "description": "Aprende a usar nuestro producto"
    },
    {
      "language": "fr",
      "title": "Visite de Bienvenue",
      "description": "Apprenez à utiliser notre produit"
    }
  ]
}

Step-Level Translations

Translate individual step content and button texts:

{
  "type": "modal",
  "title": "Welcome!",
  "content": "<p>Get started with our product</p>",
  "translations": [
    {
      "language": "es",
      "title": "¡Bienvenido!",
      "content": "<p>Comienza con nuestro producto</p>",
      "primaryButtonText": "Siguiente",
      "secondaryButtonText": "Atrás"
    },
    {
      "language": "fr",
      "title": "Bienvenue !",
      "content": "<p>Commencez avec notre produit</p>",
      "primaryButtonText": "Suivant",
      "secondaryButtonText": "Retour"
    }
  ],
  "config": {
    "primaryButtonText": "Next",
    "secondaryButtonText": "Back"
  }
}

RTL (Right-to-Left) Support

The SDK automatically handles RTL layouts for Arabic (ar) and Hebrew (he):

  • Text alignment is automatically reversed
  • Close buttons and UI elements are mirrored
  • Button order is reversed
  • dir="rtl" is applied to the HTML element
// Switch to Arabic (automatically enables RTL)
guide.setLanguage('ar');

Creating a Language Switcher

Example language switcher component:

<select id="language-switcher">
  <option value="en">English</option>
  <option value="es">Español</option>
  <option value="fr">Français</option>
  <option value="de">Deutsch</option>
  <option value="ar">العربية</option>
  <option value="he">עברית</option>
</select>

<script>
const guide = new StepBeam({
  apiUrl: 'https://api.stepbeam.com',
  onLanguageChange: (lang) => {
    document.getElementById('language-switcher').value = lang;
  }
});

document.getElementById('language-switcher').addEventListener('change', (e) => {
  guide.setLanguage(e.target.value);
});

// Load and start guide
await guide.loadGuide('welcome-tour-multilingual');
guide.start();

// Set initial language in dropdown
document.getElementById('language-switcher').value = guide.getCurrentLanguage();
</script>

Translation Best Practices

  1. Set Default Language: Always specify a defaultLanguage in your guide
  2. Provide Fallbacks: Include English translations as a fallback
  3. Test RTL Layouts: Test your guides with Arabic or Hebrew to ensure proper RTL rendering
  4. Keep Translations Consistent: Use the same language codes across all steps
  5. Translate All User-Facing Text: Don't forget button labels and tooltips
  6. Use Professional Translators: For production, use professional translation services

Supported Language Codes

The SDK supports the following ISO 639-1 language codes:

  • en - English
  • es - Spanish
  • fr - French
  • de - German
  • it - Italian
  • pt - Portuguese
  • ar - Arabic (RTL)
  • he - Hebrew (RTL)
  • ja - Japanese
  • ko - Korean
  • zh - Chinese
  • ru - Russian

Example Multilingual Guide

See the complete example in sdk/examples/multilingual-guide.json for a fully translated guide with English, Spanish, French, and German translations.

API

Constructor

new StepBeam(config: StepBeamConfig)

Config Options:

  • apiUrl (required): Base URL for the guides API
  • applicationId (required): Application ID for authentication
  • appKey (required): Application key for authentication
  • userId (required): User ID for identifying the guide viewer - persisted with all events
  • userProperties (optional): Object containing user context (e.g., { plan: 'pro', country: 'US', role: 'admin' }) - enriches all tracked events
  • apiKey (optional): API key for additional authentication
  • sessionId (optional): Session ID for event tracking (auto-generated if not provided)
  • trackEvents (optional): Whether to track events (default: true)
  • onStepComplete (optional): Callback when a step is completed
  • onGuideComplete (optional): Callback when the entire guide is completed
  • onGuideClose (optional): Callback when the guide is closed

Methods

loadGuide(guideId: string, autoStart?: boolean): Promise<void>

Load a guide from the API. If autoStart is true (default) and the guide has a trigger configuration, the trigger will be set up automatically.

start(): void

Start the loaded guide.

pause(): void

Pause the current guide.

resume(): void

Resume a paused guide.

stop(): void

Stop the guide and clean up.

next(): void

Move to the next step.

previous(): void

Move to the previous step.

getCurrentStep(): Step | null

Get the current step.

getState(): GuideState

Get the current state of the guide.

isActive(): boolean

Check if a guide is currently active.

getCurrentLanguage(): LanguageCode

Get the current active language.

setLanguage(language: LanguageCode, reRender?: boolean): void

Set the current language and optionally re-render the current step.

getAvailableLanguages(): LanguageCode[] | null

Get available languages for the current guide.

trackCustomEvent(name: string, properties?: Record<string, unknown>, context?: CustomEventContext): Promise<CustomEventResult>

Track a custom analytics event. name must match /^[a-zA-Z][a-zA-Z0-9_]*$/. properties are merged into the event metadata (max 10 KB serialised). context optionally supplies guideId, stepId, sessionId, and userId.

static validateEventName(name: unknown): { valid: true } | { valid: false; error: string }

Validate a custom event name without sending anything.

static validateEventProperties(properties: unknown): { valid: true; serialized: string } | { valid: false; error: string }

Validate custom event properties without sending anything.

Data Model

Guides are structured as follows:

interface Guide {
  id: string;
  title: string;
  description: string;
  sections: Section[];
  trigger?: Trigger; // Optional trigger configuration
}

type Trigger = PageLoadTrigger | ElementVisibleTrigger | ManualTrigger;

interface PageLoadTrigger {
  type: 'page_load';
  delay?: number; // milliseconds
}

interface ElementVisibleTrigger {
  type: 'element_visible';
  selector: string;
  threshold?: number; // 0-1 (percentage of element visible)
}

interface ManualTrigger {
  type: 'manual';
}

interface Section {
  id: string;
  title: string;
  steps: Step[];
}

type Step = ModalStep | TooltipStep | HotspotStep;

Development

# Install dependencies
npm install

# Run tests
npm test

# Build
npm run build

Testing

The SDK includes comprehensive unit tests using Vitest:

npm test

Browser Support

  • Chrome/Edge (latest)
  • Firefox (latest)
  • Safari (latest)
  • Mobile browsers (iOS Safari, Chrome Mobile)

License

MIT