Onboarding Flow
First-run onboarding built on the Guide system: a waiting beacon starts an opt-in spotlight tour, a non-modal help panel links back to the UI, a hint flags a new feature, and analytics hooks track the funnel.
Live Preview
Click the pulsing beacon (or the ⓘ) to start. Move through the tour and watch the analytics hooks fire on the right — completing it reveals the "new feature" hint.
Acme Workspace
New here? Tour analytics
onStep / onComplete / onSkip fire from the engine — the
funnel and drop-off signal that is the real value of onboarding.
No events yet — start the tour.
Key Features
- Opt-in guided tour with a spotlight on each step
- Waiting beacon as the gentle, non-intrusive tour entry
- Non-modal help panel with articles that link back to the UI
- Contextual hint flagging a brand-new feature
- Tour analytics: onStep / onComplete / onSkip funnel + drop-off
- One GuideController drives every surface
Code
Onboarding Flow Recipe
<script lang="ts">
import {
GuideProvider, Guide, GuideBeacon, GuidePanel, GuideArticle,
GuideMarker, GuideMention, GuideHint, GuideController
} from '@urbicon-ui/blocks';
import type { GuideTour } from '@urbicon-ui/blocks';
const guide = new GuideController();
let hintOpen = $state(false);
const onboardingTour: GuideTour = {
id: 'onboarding',
steps: [
{ target: 'projects', title: 'Create your first project', body: 'Your space for tasks and files.' },
{ target: 'team', title: 'Invite your team', body: 'Collaborate from day one.' },
{ target: 'api', title: 'Generate an API key', body: 'Automate anything.', interactive: true }
],
// The business value of onboarding lives here, not in the tour mechanic.
onStep: ({ index, total, via }) => analytics.track('onboard_step', { step: index + 1, total, via }),
onComplete: () => { analytics.track('onboard_complete'); hintOpen = true; },
onSkip: ({ index }) => analytics.track('onboard_skip', { droppedAt: index })
};
</script>
<GuideProvider controller={guide}>
<header>
<span>Acme Workspace</span>
<!-- UI → guide: opens the help panel at the matching article -->
<GuideMarker for="projects" />
<!-- the gentle, opt-in tour entry — hides itself once the tour is seen -->
<GuideBeacon tour={onboardingTour} />
</header>
<!-- data-guide marks each target once; tours, hints, markers + mentions all resolve to it -->
<button data-guide="projects">New project</button>
<button data-guide="team">Invite team</button>
<button data-guide="api">API keys</button>
<!-- non-modal help panel: stays open while a mention highlights the UI behind it -->
<GuidePanel title="Help">
<GuideArticle id="projects" title="Projects & workspace">
<p>A <GuideMention for="projects">project</GuideMention> groups your work.
Add people from <GuideMention for="team">team settings</GuideMention>.</p>
</GuideArticle>
</GuidePanel>
<!-- contextual hint, revealed after the tour completes -->
<GuideHint for="api" trigger="manual" open={hintOpen} title="New: API keys"
onDismiss={() => (hintOpen = false)}>
Generate scoped API keys for automation.
</GuideHint>
<!-- mount the tour renderer once; invisible until a tour starts -->
<Guide />
</GuideProvider>