Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelogContact
  1. Home
  2. Blog
  3. Build it: screens and apps
  4. Onboarding Checklist UI: The Get Started Card in React
Auf Deutsch lesen
  1. Blog
  2. Build it: screens and apps
  3. Onboarding Checklist UI: The Get Started Card in React
Build it: screens and apps
Build it: screens and apps

Onboarding Checklist UI: The Get Started Card in React

SR
Serban Rusu · Founder of Wingo UI
Nov 6, 2026 · 9 min read

On this page

0%
  1. What tasks belong on a SaaS onboarding checklist?
  2. How do I build the Get started card in React?
  3. Where should onboarding checklist progress live?
  4. How should dismiss and reopen work?
  5. When should the checklist become a floating launcher?
  6. How does the checklist hand off to a product tour without nagging?
  7. Does it work on phones and with a keyboard?
  8. How does it compare to shadcn onboarding checklist blocks?
  9. How do I add it to my app?
  10. FAQ
    1. How many tasks should an onboarding checklist have?
    2. Should an onboarding checklist start partly complete?
    3. Where should I store onboarding checklist progress?
    4. Can people hide the onboarding checklist and get it back?
    5. Is there a shadcn onboarding checklist component?
    6. Is the Wingo UI Setup Checklist free?

TL;DR

A good onboarding checklist UI is a Get started card on the dashboard with three to five tasks, each with a button that does the task, and a progress count based only on real work. Store progress and the dismissal on the user record so it survives a new device, let people hide it and bring it back from a Help menu, and use a floating launcher on pages without room for a card. Start the product tour from a checklist task instead of auto-starting both.

Published Nov 6, 2026

The onboarding checklist UI is the Get started card a new customer sees on the dashboard after sign up: four or five tasks, a progress bar, a button next to each task. Plenty of onboarding checklist React examples stop at a list with checkboxes. A real one has to answer harder questions: which tasks go on it, where the progress is saved, what happens when someone hides it, how it fits on a phone, and how it hands off to a product tour without nagging. This guide answers each one with the Wingo UI Setup Checklist and plain Next.js code you can copy.

What tasks belong on a SaaS onboarding checklist?

The tasks that get a new account to its first real result. For an invoicing app that is connecting payments and sending a first invoice, not filling in a bio. A useful SaaS onboarding checklist follows four rules:

  1. Three to five counted tasks. Each one should move the account closer to doing the job it signed up for.
  2. Every task has an action. "Connect Stripe" opens the Stripe flow. A task people can only read about is a to-do note, not onboarding.
  3. Optional steps stay out of the count. "Get the mobile app" is nice to have. Tag it optional so the bar can reach 100% without it.
  4. Real head starts only. If sign up already created the workspace, show that task as done. In their endowed progress study (opens in a new tab) (Journal of Consumer Research, 2006), Nunes and Drèze gave car wash customers loyalty cards with two of ten stamps already filled in, and those customers were more likely to finish the card than people with a blank card of eight. On a checklist, credit only steps the person really did, so the head start stays honest. A bar that says 20% for opening the app reads as a trick.

How do I build the Get started card in React?

A get started checklist is one component with a list of items. Install it with npx wingo-ui@latest add setup-checklist. The CLI copies setup-checklist.tsx into components/ui along with the Progress bar, Button and Popover it uses, and installs motion and lucide-react. Then pass it the tasks:

tsx
"use client";
import { useState } from "react";
import { Building2, CreditCard, FileText, Palette, Smartphone } from "lucide-react";
import { SetupChecklist, type SetupChecklistItem } from "@/components/ui/setup-checklist";
const items: SetupChecklistItem[] = [
{ id: "workspace", title: "Create your workspace", icon: <Building2 /> },
{
id: "logo",
title: "Add your logo",
description: "It shows on invoices and the client portal.",
icon: <Palette />,
action: { label: "Upload logo", href: "/settings/brand" },
},
{
id: "payments",
title: "Connect payments",
description: "Let clients pay by card or bank transfer.",
icon: <CreditCard />,
action: { label: "Connect Stripe", href: "/settings/payments" },
},
{
id: "invoice",
title: "Send your first invoice",
icon: <FileText />,
action: { label: "Create invoice", href: "/invoices/new" },
},
{ id: "app", title: "Get the mobile app", icon: <Smartphone />, optional: true, action: { label: "Text me a link" } },
];
export function GetStarted() {
const [completed, setCompleted] = useState<string[]>(["workspace"]);
return <SetupChecklist items={items} completed={completed} onCompletedChange={setCompleted} />;
}

Zero props beyond the items already gives you a finished card: the title "Get started", an "x of y done" count with a bar, the first open task expanded, one task open at a time. Wiring onCompletedChange turns each round check into a checkbox people can toggle. Without it the checks only show state, which is what you want when the server decides what is done. An item with its own done stays read-only either way. When the last counted task is checked, a "You're all set" panel replaces the list and the card folds up after doneDelay (4000 ms by default; 0 keeps it open).

Check a step off: the tick pops in, the bar fills and the next open step expands. Fold the card with its header.
$ npx wingo-ui@latest add setup-checklist
ProSetup Checklist docs

tone defaults to neutral, and we keep it there on dashboards because a brand-orange card competes with the page's main action. size="sm" with variant="inline" fits the card into a sidebar.

Where should onboarding checklist progress live?

On the server. Progress in React state or local storage resets on a new laptop and goes stale when someone connects Stripe from the settings page instead of the card. Split the tasks in two kinds:

  • Tasks your data already knows. Logo uploaded, Stripe connected, first invoice sent. Compute them on the server and pass done on the item. An item's done wins over completed, so the check cannot drift from reality.
  • Tasks only the person can confirm. "Watched the tour", "Skipped the mobile app". Keep those ids in a small record on the user and save it with a server action.
tsx
// app/(app)/dashboard/page.tsx (server component)
import { getOnboarding } from "@/lib/onboarding"; // your data layer
import { GetStarted } from "./get-started";
export default async function Dashboard() {
const o = await getOnboarding();
return (
<GetStarted
facts={{ workspace: true, logo: o.hasLogo, payments: o.stripeConnected, invoice: o.invoiceCount > 0 }}
manual={o.manualDone}
dismissed={o.dismissedAt !== null}
/>
);
}
tsx
// app/(app)/dashboard/get-started.tsx
"use client";
import { useState } from "react";
import { SetupChecklist } from "@/components/ui/setup-checklist";
import { saveOnboarding } from "./actions"; // "use server" function that writes manualDone / dismissedAt
import { items } from "./checklist-items";
type Props = { facts: Record<string, boolean>; manual: string[]; dismissed: boolean };
export function GetStarted({ facts, manual, dismissed }: Props) {
const [completed, setCompleted] = useState(manual);
if (dismissed) return null;
return (
<SetupChecklist
items={items.map((item) => (item.id in facts ? { ...item, done: facts[item.id] } : item))}
completed={completed}
onCompletedChange={(next) => {
setCompleted(next);
void saveOnboarding({ manualDone: next });
}}
onDismiss={() => void saveOnboarding({ dismissed: true })}
/>
);
}

Data-backed tasks flip to done on the next render, wherever they were finished. If your action really finishes the task in place (a Connect button that runs the whole OAuth flow in a popup), markOnAction checks the item off when its main action is clicked.

How should dismiss and reopen work?

Dismiss hides the card for this person until they ask for it again. The x in the header (and the Dismiss button in the done state) hides the component and calls onDismiss. Save that, or the card comes back on the next page load and people learn to ignore it.

Reopening is your part. Put a "Setup guide" item in the Help or account menu that calls a server action to clear dismissedAt and revalidatePath("/dashboard"). The dashboard renders again with dismissed false, the checklist mounts fresh and shows today's progress with every data-backed task up to date. Two details matter:

  • Keep skipping one task and dismissing the whole list as separate actions. Give the Invite your team task a secondaryAction such as "Skip for now" whose onClick adds that id to completed and saves it, so the rest of the list stays.
  • Retire the card when the account is clearly active. Someone who has sent ten invoices without a logo does not need it; set the same dismissedAt flag on the server.

When should the checklist become a floating launcher?

When the page has no room for a card, or when the checklist should follow people around the app. variant="floating" renders a pill in the bottom corner with the title and the count. It opens the list in a popover on desktop and a bottom sheet below 768px, and it sits clear of the iPhone home indicator through safe-area insets. The demo below starts in the floating variant: tap the pill.

Tap the launcher in the corner: the list opens in a popover on desktop and in a bottom sheet at phone width.
$ npx wingo-ui@latest add setup-checklist
ProSetup Checklist docs

A pattern that works well: the card on the dashboard home, the launcher on other pages until the account finishes or dismisses it, both reading the same server record. The floating panel always starts closed, so it never covers the page on load.

How does the checklist hand off to a product tour without nagging?

Make the tour a task instead of a pop-up. A tour that auto-starts over a checklist that also wants attention is the worst first visit. Put "Take the 1 minute tour" on the list as an optional task, start the Tour from its action, and check the task off when the tour ends either way:

tsx
"use client";
import { useRef, useState } from "react";
import { Compass } from "lucide-react";
import { SetupChecklist, type SetupChecklistItem } from "@/components/ui/setup-checklist";
import { Tour, type TourApi, type TourStep } from "@/components/ui/tour";
const steps: TourStep[] = [
{ id: "new", target: "#new-invoice", title: "Create an invoice", content: "Every invoice starts here." },
{ id: "clients", target: "#clients-nav", title: "Your clients", content: "Contacts, history and balances." },
];
export function GetStartedWithTour({ items }: { items: SetupChecklistItem[] }) {
const tour = useRef<TourApi | null>(null);
const [completed, setCompleted] = useState<string[]>([]);
const finish = () => setCompleted((ids) => (ids.includes("tour") ? ids : [...ids, "tour"]));
const withTour: SetupChecklistItem[] = [
...items,
{
id: "tour",
title: "Take the 1 minute tour",
icon: <Compass />,
optional: true,
action: { label: "Start tour", onClick: () => tour.current?.start() },
},
];
return (
<>
<SetupChecklist items={withTour} completed={completed} onCompletedChange={setCompleted} />
<Tour steps={steps} persistKey="acme:tour" setApi={(api) => { tour.current = api; }} onComplete={finish} onSkip={finish} />
</>
);
}

No autoStart here on purpose. The person chooses when to see the tour, persistKey remembers in local storage that it was finished or skipped, and start() still replays it from the Help menu later. Local storage is per browser, so in production finish should also save the tour id with the other manual ids, as in the server example above; that record is the one that follows people to a new device. With the floating variant, control its open prop and close the panel before calling start(), so the spotlight is not hidden behind the list. For the full tour setup, including the docked phone card, read our guide to the React product tour.

The checklist comes after the first-run flow, not inside it. Welcome slides, permission asks and the profile step belong to the Onboarding Flow, which ends on the dashboard where the checklist picks up (see our React onboarding flow tutorial).

Does it work on phones and with a keyboard?

Yes. Each task header is a real button with aria-expanded, and the check is a role="checkbox" with aria-checked once you wire onCompletedChange. Tab reaches each task, ArrowUp, ArrowDown, Home and End move between them, Enter or Space expands one, and Space toggles a focused check. The progress bar gets its name from the count text, so a screen reader hears "2 of 4 done". On touch screens the rows grow to 44px, and below 640px the action buttons go full width, so a thumb lands on the task it meant.

How does it compare to shadcn onboarding checklist blocks?

shadcn/ui has no checklist component of its own, so a shadcn onboarding checklist comes from a third-party registry. What the public pages say, as of November 6, 2026:

OptionWhat the page showsSaved progressAccess
shadcn.io Setup Checklist block (opens in a new tab)One step open at a time, a count with a progress line, "Hide guide" collapses it into a pill that brings it backThe page says nothing is saved and you store the flags with the accountPart of shadcn.io Pro; the site says it is not affiliated with shadcn/ui
21st.dev Onboarding Checklist (opens in a new tab)Collapsible steps with completed, in-progress and pending statesNot documentedInstalls with a 21st API key; license listed as unknown
Wingo UI Setup ChecklistCard, inline and floating variants, done state, optional tasks, bottom sheet on phonesControlled completed and per-item done from your dataWingo UI Pro

A community block is fine for a prototype. For production, check saved progress, the phone layout and keyboard support before you pick one.

How do I add it to my app?

Run npx wingo-ui@latest add setup-checklist, map your setup tasks to items with done from your own data, and save the manual ids and the dismissal on the user. The Setup Checklist and the Tour are part of Wingo UI Pro ($8 a month, $80 a year or $150 once); the Progress bar is free if you would rather build a simpler card yourself. If you need the dashboard around it too, the Pro admin dashboard page block gives you the shell and a home screen to put the card on. More complete screens are in the Build it: screens and apps category, starting with the Next.js admin dashboard tutorial.

Components in this post

  • Setup Checklist

    The dashboard Get started card: setup tasks with progress and actions, collapsible and dismissible, or a floating launcher.

    Pro
  • Onboarding Flow

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

    Pro
  • Progress

    A React progress bar, stepped bar or ring for uploads and quotas, determinate or indeterminate, with a label, value, tones and thresholds.

    Free
  • Tour

    A React product tour that dims the page around the real UI, explains each step in a card, docks at the bottom on phones and adds hotspots.

    Pro

FAQ

How many tasks should an onboarding checklist have?

Three to five tasks that each lead to a real result, such as connecting payments or sending a first invoice. Mark nice-to-have steps as optional so they stay out of the count, and move advanced settings to the places where people need them.

Should an onboarding checklist start partly complete?

Only with steps people really did, such as creating the workspace during sign up. A head start based on finished work helps people see they are already on the way; a bar that credits nothing feels like a trick.

Where should I store onboarding checklist progress?

On the server, next to the user or workspace. Derive tasks like Connect Stripe from your own data and save the manual ones and the dismissal in one small record, so progress follows people to a new phone or browser.

Can people hide the onboarding checklist and get it back?

They should be able to. Hide it on dismiss, save the dismissal, and add a Setup guide item to the Help or account menu that clears the flag and shows the card again.

Is there a shadcn onboarding checklist component?

shadcn/ui itself has no checklist component as of November 2026. Third-party registries such as shadcn.io and 21st.dev list onboarding checklist blocks, and the Wingo UI Setup Checklist installs the same way with npx wingo-ui@latest add setup-checklist.

Is the Wingo UI Setup Checklist free?

No. The Setup Checklist, the Tour and the Onboarding Flow are Pro. The Progress component, which you can use to build a simpler card yourself, is free.

Try it in your project

Setup Checklist

Pro

The dashboard Get started card: setup tasks with progress and actions, collapsible and dismissible, or a floating launcher.

75 components free, no account needed. Pro from $8 a month.

Open Setup Checklist liveSee pricing
  • Onboarding
  • SaaS
  • Dashboard
  • React
  • Mobile UI

Share

SR

About the author

Serban Rusu

Founder of Wingo UI

Serban Rusu founded Wingo UI. He builds its component library, CLI and MCP server, and writes about React interfaces for phones and AI coding agents.

More from Serban
Keep reading

Related posts

All posts
Component guides

React Product Tour: Spotlight, Phone Dock, Hotspots

Build a React product tour that spotlights the real UI, docks at the bottom on phones and remembers who finished it, plus when a hotspot is the better choice.

SRSerban Rusu·Oct 19, 2026·9 min read
Build it: screens and apps

React Onboarding Flow: Slides, Permissions, Install

Build a React onboarding flow in Next.js: skippable welcome slides, notification and location asks people can refuse, saved progress, then an install prompt.

SRSerban Rusu·Oct 16, 2026·9 min read
Mobile UI in React

React PWA Install Prompt for Chrome, Edge and iPhone

Build a React PWA install prompt in Next.js: catch beforeinstallprompt in Chrome and Edge, show Add to Home Screen steps on iPhone, and know when not to ask.

SRSerban Rusu·Oct 9, 2026·9 min read
Newsletter

Get new posts by email

New posts, product news and occasional offers from Wingo UI. We count clicks to keep it relevant.

No spam. Unsubscribe at any time.

WingoUI

Animated, configurable, mobile-first React components and blocks. Copy the source, make it yours, and let your coding agent build with it.

Product

  • Components
  • Templates
  • Pricing
  • AI agents
  • For teams
  • Theme generator

Resources

  • Docs
  • Contact
  • Programs
  • Blog
  • Changelog
  • Changelog RSS
  • llms.txt

Compare

  • Wingo UI vs paid kits
  • Wingo UI vs shadcn/ui
  • shadcn/ui alternatives
  • MUI alternatives
  • Tailwind Plus alternatives
  • Magic UI alternatives
  • Free components

Legal

  • Terms
  • Privacy
  • Refunds
  • License
  • Imprint

Component categories

  • Buttons & Actions
  • Inputs
  • Forms
  • Navigation
  • Overlays
  • Feedback
  • Data Display
  • Tables & Lists
  • Charts & Stats
  • Layout
  • Media
  • AI Kit
  • Text & Effects
  • Mobile
  • Commerce
  • Marketing Sections
  • Blocks
  • Hooks & Utilities

© 2026 Wingo UI

Wingo UI