Onboarding Flow
A four-step onboarding form with progress, per-step validation, an async URL check and a finished state.
Overview
First-run onboarding that respects people’s time. A segmented progress bar shows the step you’re on and fills half-way while you’re on it. Steps slide in from the direction you’re travelling. Each step validates before moving on, with the error in plain words beside the button.
The workspace URL is derived from the name until you edit it yourself, and is checked asynchronously against taken slugs. Team size is a radio group, goals are multi-select, and invites accept any mix of commas, spaces and newlines, with a live count of valid addresses and a precise error for the bad ones.
Use it as a template for any multi-step form: account setup, applications, configuration wizards. Change STEPS and the step bodies, and keep the navigation and validation.
When to use
- Collecting input where the control itself should guide people.
When not to use
- Cases a plain native input already serves well.
Installation
pnpm dlx shadcn@latest add https://sundaeui.dev/r/onboarding-flow.jsonnpx shadcn@latest add https://sundaeui.dev/r/onboarding-flow.jsonyarn dlx shadcn@latest add https://sundaeui.dev/r/onboarding-flow.jsonbunx --bun shadcn@latest add https://sundaeui.dev/r/onboarding-flow.jsonWorks in any React project. Files are written to components/sundae/. Read the source in the stage’s Code view. Pro assets need a personal token. See authenticated installs.
- No dependencies beyond React 18 or later.
- Copy onboarding-flow.tsx into components/sundae/.
- Make sure Tailwind scans that folder (v4 detects it automatically; v3 needs it in `content`).
- Import the component and use it as shown below.
Usage
import { OnboardingFlow } from '@/components/sundae/onboarding-flow'
<OnboardingFlow
checkSlug={async (slug) => ((await api.slugTaken(slug)) ? 'That URL is taken.' : null)}
onFinish={(data) => api.createWorkspace(data)}
/>Props
| Prop | Type | Default |
|---|---|---|
onFinish*Called with { workspace, url, size, goals, invites }. Throw to show an error. | (data: OnboardingData) => Promise<void> | — |
checkSlugReturns an error message when the slug is unavailable. | (slug) => Promise<string | null> | — |
Accessibility
- Progress is an ordered list with aria-current="step". Each step is a fieldset with a legend.
- Choices use radio and pressed semantics. Errors are announced via role="alert".
- Enter submits the current step, and Back never loses data.
Customization
- Edit STEPS, SIZES and GOALS, or replace step bodies with your own fields.
- Swap app.example.com for your domain.
FAQ
- Is Onboarding Flow free?
- Onboarding Flow is part of Sundae Pro. The live preview is open to everyone; the source installs with a Pro account.
- How do I install Onboarding Flow?
- Run npx shadcn@latest add https://sundaeui.dev/r/onboarding-flow.json. The files are written to components/sundae/. It has no dependencies beyond React 18 or later.
- Does Onboarding Flow support keyboard and screen readers?
- Progress is an ordered list with aria-current="step". Each step is a fieldset with a legend. Choices use radio and pressed semantics. Errors are announced via role="alert".
- Does Onboarding Flow respect reduced motion?
- Yes. With prefers-reduced-motion set, decorative motion is removed and state changes are instant.
More like this
All forms →OTP Field
Forms · RefinedJelly Switch
Forms · Playful- Pro
Drop Zone
Forms · Refined Date Picker
Forms · UnderstatedCombobox
Forms · UnderstatedRange Slider
Forms · Understated