Everything in the box.
Steppr is intentionally narrow - tours, checklists, announcements, a Resource Center launcher, native integrations, and the bits that make them useful. No NPS module, no full in-app messaging suite, no survey tool. The sections below are how each primitive is actually built and how it behaves on your site.
Tooltip, modal, hotspot - anchored to anything.
The bread and butter. Tours are sequences of steps, each anchored to a CSS selector or rendered modally. Pick visually with the click-to-build picker; Steppr generates the sturdiest selector available.
- Three step types: tooltip (anchored), modal (centred), hotspot (passive, click-to-reveal)
- Click-to-build picker via ?steppr_edit=true - no Chrome extension required
- Markdown body fields with a built-in toolbar (bold, italic, code, link)
- Two advance modes: Next button or anchor-click (advance the tour as the user clicks the highlighted element itself)
- Require-to-advance gates: the next button only enables when the anchor input has a value, or when a steppr.track() event fires
- MutationObserver retries for SPA elements that mount async; resume across full page navigations
- Spotlight backdrop, scroll-aware positioning, smart placement above/below
Persistent onboarding programs that auto-complete.
A floating widget bottom-right of your app. Items auto-tick when their action fires - a tour completes, a URL matches, or steppr.track() fires with the matching event name. Or the end user can check them manually.
- Three action types per item: launch a tour, visit a URL, or fire on a steppr.track() event
- State persists per end-user, cross-device, keyed on identify()
- Items pre-tick on first sight if the user has already done them (no "reset" feeling for existing users)
- Disable manual completion when you want proof-of-action only - items can’t be ticked by clicking, only by their action firing
- Themed to match your brand via the same per-flow theme presets used by tours and announcements
- Backfilled completion: existing customers see existing progress reflected
- Connect snippet
- Create first project
- Invite a teammateVisit URL - /team
- Launch first tourLaunch tour - Welcome
Banner or modal - broadcast a single message, once per user.
One-shot messages for shipping news, scheduled maintenance, or pricing changes. Pick modal (centred card with backdrop) or banner (top-of-page strip, no layout shift). Optional CTA with click analytics.
- Two display variants: modal (centred card) and banner (fixed top-of-page strip)
- Three banner placements: overlay (no layout shift), pushdown (page content drops below it), or inline (scrolls away with the page)
- One-shot dismiss - once an end user closes it, they don’t see it again
- Optional CTA button with label + URL; opens in the same tab or a new tab; clicks recorded as a separate event
- Same targeting + triggers as tours: URL match, traits, page-load, event-based
- Banner and modal can co-exist on the page; only one of each runs at a time
One launcher. Tours, checklists, announcements, links.
A persistent button on your customer’s site (bottom-right or bottom-left) opens a slide-out panel listing every flow available to that end user, recent announcements they can revisit, and up to ten custom links - help docs, changelog, support.
- Per-workspace launcher widget - opt-in, off by default
- Sections you can toggle: tours, checklists, recent announcements (last N), custom links (up to 10)
- Per-flow opt-out: any tour, checklist or announcement can be hidden from the launcher while still firing automatically
- Position: bottom-right or bottom-left
- Customizable header label and intro line
- Welcome tour
- Onboarding checklist
- v2 changelog
- Help docs · Status · Reach support
Show the right tour to the right user at the right moment.
Targeting decides who is eligible to see a tour or checklist. Triggers decide when it fires. Both use the same primitives so you don't have to learn two systems.
- URL targeting: contains, exact match, or regex
- Trait targeting: set via steppr.identify(userId, { plan: "pro", … })
- Triggers: page load, URL change, or steppr.track() event by name (Growth+)
- AND-ed targeting rules - every rule must pass for the user to be eligible
- OR-ed triggers - any trigger fires the tour for an eligible user
Two lenses on every tour: users and attempts.
Per-tour funnel, completion rate, dismissal rate, drop-off detection. Read replays separately from unique users so a single buggy auto-firing tour can't pollute your conversion numbers.
- Per-step reach (unique end-users + raw attempts)
- Drop-off detection between steps - find where users bail
- User-level rates (did this person ever finish?) and attempt-level rates (per run)
- Retention: 90 days on Starter, up to 730 days on Scale
- Last-event timestamp so you know if data is stale
- Step 1100%
- Step 278%
- Step 364%
- Step 441%
One default, plus presets you pick per flow.
Set a workspace default that every tour, checklist, and announcement inherits. Want a campaign-specific look on a single announcement, or a different palette on one tour? Save it as a preset and pick it from a dropdown on the editor - no global theme edits, no churn.
- Workspace default: primary colour, corner radius, font family, font size, text alignment, button alignment
- Up to 20 named presets stored on the workspace; picked per tour, checklist, or announcement
- Resolved at publish time - the SDK reads a frozen theme from the snapshot, no preset lookup on the hot path
- "Match site font" inherits from the customer’s page so flows feel native; or pick the system sans stack
- Three font-size scales (compact, default, roomy) - the whole card scales off one base value
- Plan-aware branding: Growth+ removes the "Powered by Steppr" badge
- Renders inside a Shadow DOM root - your CSS can’t leak in, ours can’t leak out
- Workspace defaultDefault
- Spring campaign
- Onboarding tours
- Pricing announcement
Pipe events out. Slack, webhooks, Segment, Zapier.
Forward tour, checklist, and announcement events to Slack channels, generic HTTPS webhooks, or your Segment workspace. One delivery worker handles HMAC signing, exponential-backoff retries, and auto-pause on sustained failures so a flaky endpoint can’t break Steppr.
- Generic webhooks: HMAC-SHA256 signed JSON, replay-protection timestamps, idempotency event ids
- Slack: paste an incoming-webhook URL, pick events, get formatted block-kit messages in your channel
- Segment outbound: forward Steppr events to your Segment workspace via the track API
- Segment inbound: pipe identify/track from Segment into Steppr without re-instrumenting steppr.identify on your site
- Test endpoint, deliveries log, manual retry, signing-secret rotation - all from the dashboard
- Auto-pause on 5 consecutive failures + email alert; resume in one click after fixing
- Zapier on the roadmap; today, point Webhooks-by-Zapier at the generic endpoint
- Slack #activationtour.completed · announcement.cta_clicked
- Webhook · api.example.comall events · HMAC-signed
- Segment · prod-write-keymapped to track() events
- Webhook · stagingpaused after 5 failures
X-Steppr-Signature: t=1715346721,v1=…
{ "type": "tour.completed", "endUserId": "u_42", … }
One snippet. Around 23 kilobytes on the wire.
Drop a single script tag into your <head>. The SDK renders inside its own Shadow DOM root, patches history.pushState to detect SPA routes, and uses MutationObserver to wait for elements that mount async.
- ~23 KB gzipped, defer-loaded, never blocks paint - everything ships in one bundle (tours, checklists, announcements, Resource Center)
- Shadow DOM isolation prevents CSS bleed in either direction
- Auto SPA route detection (history pushState/popstate)
- identify() and track() hooks for trait and event-based personalisation
- No npm install, no React component, no framework lock-in - vanilla JS works in any stack
// after the snippet loads
window.Steppr.identify('user_42', {
plan: 'pro',
company: 'Acme'
});
// fire an event-based trigger
Steppr.track('invite_sent');