Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCountry SelectCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputEmoji PickerFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone SelectTree Select
Forms
Address InputBooking WidgetCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage GalleryImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadChat WidgetConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeTerminalText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowOrder History PagePost Listing WizardPricing PageProfile PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAgency PageAI Product PageAppointment Booking PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageHome Services PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePortfolio PagePress PageProduct Tour PagePromo PageReal Estate PageReferral PageResearch Report PageRestaurant PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageStorefront PageSwitch PageTemplate Gallery PageTravel PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Blocks

Onboarding Flow

Blocks

Onboarding Flow React block for Tailwind CSS v4

Mobile App HomeOrder History Page
Live props
State
defaultStep
loading
Behavior
minInterests3
simulatePermissions
persistKey
showSkip
allowRestart
Layout
art
Appearance
tone
radius
animateIn
Content
locale
Code
import { OnboardingFlow } from "@/components/blocks/onboarding-flow"

<OnboardingFlow />
  1. Home
  2. Components
  3. Blocks
  4. Onboarding Flow
Pro

Onboarding Flow React block for Tailwind CSS v4

v1.0.2·Updated in 1.9.0

A React onboarding flow for a marketplace app: welcome slides, notification and location asks, a short profile, preferences and a finish.

Swipe or drag the three welcome slides, use the dots, the arrow keys or Continue; Skip on the slides and Get started on the last one go to the permissions. From there a header shows a back button, a three part progress bar and Skip, which jumps straight to the finish with what you entered so far; every step change slides in from the side it belongs to, moves focus to the step title and is announced ("Step 2 of 4: Permissions"). Permissions: Allow opens the real browser prompt for notifications or location (with simulatePermissions it answers after 600 ms), Not now skips it; each card then shows Allowed, Denied with where to change it, Skipped with Allow anyway, or why the browser cannot do it. Continue is always enabled. A granted location fills the city with the nearest one. Profile: tap the photo to choose, crop or take a picture (optional), type the name, search the city (a full height sheet on phones), and tap interest chips, which are toggle buttons; the counter turns green at the minimum. Continue with a missing name or too few interests shows the errors and focuses the first. Preferences: pick Instantly, Daily or Weekly, toggle the newsletter card and read the summary line update. Finish celebrates with a bouncy check and one ring pulse (and a success haptic on phones), then Go to Home finishes and Start over starts over. Everything you enter is saved as you go, so a reload resumes on the same step with a short "Picking up where you left off" note. On laptops a picture beside the card cross fades per step and per slide; on phones the flow fills the screen with the main button pinned above the safe area. With reduced motion steps cross fade and the check simply appears.

Onboarding Flow is a Pro React block in the React blocks category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add onboarding-flow, together with Alert, Avatar Upload, Button, Combobox, Image Cropper and 15 more and the npm packages motion, lucide-react, react-hook-form and zod.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add onboarding-flow

Onboarding Flow is part of Pro, with 298 more Pro items: $8 a month or $150 once. 14-day refund before you download any Pro item. See plans

Usage

Import OnboardingFlow from @/components/blocks/onboarding-flow.

// app/(app)/welcome/page.tsx
"use client";

import { useRouter } from "next/navigation";
import { OnboardingFlow } from "@/components/blocks/onboarding-flow";

export default function Page() {
  const router = useRouter();
  return (
    <OnboardingFlow
      user={{ name: "Emma Carter" }}
      persistKey="onboarding:ana"
      onUpload={async (blob) => {
        const response = await fetch("/api/avatar", { method: "POST", body: blob });
        if (!response.ok) throw new Error("Upload failed");
        return (await response.json()).url;
      }}
      onComplete={async ({ profile, preferences, permissions }) => {
        await fetch("/api/onboarding", { method: "POST", body: JSON.stringify({ profile, preferences, permissions }) });
        router.push("/");
      }}
    />
  );
}

Props

  • defaultStepdefault "welcome"
    OnboardingStep

    The step shown first (uncontrolled, and the fallback before storage is read): "welcome" | "permissions" | "profile" | "preferences" | "done".

  • step
    OnboardingStep

    The current step, controlled (then nothing is restored from storage for it).

  • onStepChange
    (step: OnboardingStep) => void

    Runs on every step change (mirror it to the URL).

  • slides
    OnboardingSlide[]

    The welcome slides (onboarding-carousel's slide shape). Default: the three Acme Market slides from ONBOARDING_FLOW_SAMPLE with their vignettes and the side panel pictures; custom slides show their image in the side panel.

  • interests
    OnboardingInterest[]

    The chips of the profile step: { id, label, icon, description }. Default: the 12 Acme Market categories of ONBOARDING_FLOW_SAMPLE.interests; icon takes a node or a sample icon name.

  • minInterestsdefault 3
    number

    How many interests the profile needs; 0 makes them optional.

  • permissions
    ("notifications" | "location")[]

    The permissions asked for, default both; [] skips the step.

  • simulatePermissionsdefault false
    boolean

    Answer granted after 600 ms instead of calling the browser (demos, tests); a simulated location is Gheorgheni, Cluj-Napoca.

  • user
    OnboardingUser

    The signed-up person ({ name, avatar, city }): the name the profile starts with and the side panel's profile card. Default ONBOARDING_FLOW_SAMPLE.user (Emma Carter).

  • defaultProfile
    OnboardingProfile

    The profile the flow starts with ({ avatar, name, city, interests }); default empty with the name from user.

  • profile
    OnboardingProfile

    The profile, controlled; onProfileChange gets every draft change.

  • onProfileChange
    (profile: OnboardingProfile) => void

    Every change of the profile draft (photo, name, city, interests).

  • defaultPreferences
    OnboardingPreferences

    The preferences the flow starts with; default { frequency: "daily", newsletter: false }.

  • preferences
    OnboardingPreferences

    The preferences, controlled; onPreferencesChange gets every change.

  • onPreferencesChange
    (preferences: OnboardingPreferences) => void

    Every change of the frequency or the newsletter switch.

  • persistKeydefault "onboarding-flow"
    string

    Local storage key that keeps the step, the drafts and the permission answers, so a closed app resumes where it stopped; empty keeps them in memory.

  • showSkipdefault true
    boolean

    Skip on the slides and in the header of the later steps.

  • allowRestartdefault true
    boolean

    The Start over button on the finish screen, which clears the saved progress.

  • artdefault "image"
    "image" | "none"

    The picture beside the card from 1024px, cross fading per step and per slide (tablets show the card alone, centered); none centers the card alone everywhere.

  • onComplete
    (result: OnboardingFlowResult) => (void | Promise<unknown>)

    Go to Home: gets { profile, preferences, permissions } (each permission granted, denied or skipped); a promise spins the button. Default: the toast "Welcome to Acme Market".

  • onUpload
    (blob: Blob, context: AvatarUploadContext) => Promise<string | void>

    Uploads the cropped photo and resolves its url. Default: simulated for 900 ms, then kept as a data url; a failed upload shows a note and the flow continues without a photo.

  • tonedefault "neutral"
    Tone

    The primary buttons, the progress bar, the selected chips, the frequency thumb, the switch and the slides' button and dots.

  • radiusdefault "md"
    "sm" | "md" | "lg"

    The card and the side panel, the permission tiles and the controls' corners.

  • loadingdefault false
    boolean

    The card as skeletons of the profile step and a pulsing side panel.

  • animateIndefault true
    boolean

    The side panel and the card rise in once when the page mounts on the client (server html is already final).

  • labels
    Partial<OnboardingFlowLabels>

    Every visible string: DEFAULT_ONBOARDING_FLOW_LABELS (English) by default; carousel, avatarUpload, cropper and validation carry the composed items' strings.

  • localedefault "en-US"
    string

    Prices and distances on the slides and the page language (lang).

  • classNames
    Partial<Record<OnboardingFlowSlot, string>>

    Classes for art, main, card, header, progress, step, title, description, footer, permission, interests and done.

Parts

  • DEFAULT_ONBOARDING_FLOW_LABELS

    constant

    The English strings for every visible label, the default of labels. Type: OnboardingFlowLabels.

  • ONBOARDING_FLOW_LABELS_EN

    constant

    The same English strings under their older name, kept for existing imports.

  • ONBOARDING_FLOW_SAMPLE

    constant

    The demo data: the user, a simulated position, the slides, interests, nearby listings, a sample posting and the art.

  • OnboardingFlowProps

    type

    Props of OnboardingFlow, including the div attributes of the root.

  • OnboardingFlowResult

    type

    What onComplete receives: { profile, preferences, permissions }.

  • OnboardingStep

    type

    "welcome" | "permissions" | "profile" | "preferences" | "done", the values of step and defaultStep.

Examples

Open

Permissions

Notifications and location with the reason for each; Allow answers after 600 ms here, Not now skips.

Open

Profile, too few interests

Two interests picked out of the three needed: the counter, the error and the focus on the chips.

Open

Done

The finish: a bouncy check with one ring pulse, three tips, Go to Home and Start over.

Open

Brand tone

tone="brand" on the buttons, the progress, the chips, the frequency thumb and the switch.

Open

British English

The default labels with locale en-GB, from the first slide.

Open

No picture, no permissions

art="none" centers the card alone and permissions={[]} leaves the step out.

Dependencies

motionlucide-reactreact-hook-formzodalertavatar-uploadbuttoncomboboximage-cropperinputonboarding-carouselprogresssegmented-controlswitchtagtoastuse-persisted-statecommerceform-validationhapticsmotionro-locationstonesui-config

Files

  • components/blocks/onboarding-flow.tsx
  • components/blocks/onboarding-flow-data.ts

FAQ

Is the React Onboarding Flow block free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install Onboarding Flow?

Run npx wingo-ui@latest add onboarding-flow. It also adds the Wingo UI items it builds on (Alert, Avatar Upload, Button, Combobox, Image Cropper and 15 more) and the npm packages motion, lucide-react, react-hook-form and zod. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/onboarding-flow.

How does Onboarding Flow behave on phones?

Profile: tap the photo to choose, crop or take a picture (optional), type the name, search the city (a full height sheet on phones), and tap interest chips, which are toggle buttons; the counter turns green at the minimum.

See also

Onboarding CarouselAvatar UploadStepsRegister PageMobile App Home

More React blocks

Login PageMarketplace Home PageAdmin Dashboard PageAdmin ShellAI Chat PageAPI Keys Page
All 26 React blocks

Articles using this component

  • Onboarding Checklist UI: The Get Started Card in React

    Build it: screens and apps · Nov 6, 2026 · 9 min read

  • React Product Tour: Spotlight, Phone Dock, Hotspots

    Component guides · Oct 19, 2026 · 9 min read

  • React Onboarding Flow: Slides, Permissions, Install

    Build it: screens and apps · Oct 16, 2026 · 9 min read

  • React PWA Install Prompt for Chrome, Edge and iPhone

    Mobile UI in React · Oct 9, 2026 · 9 min read

PreviousMobile App HomeNext Order History Page