Once UI Handbook
Beginner Guides
What is Once UI?
Install & config
Page skeleton
Your first page
Build And Launch
How to launch a portfolio site that actually gets you hired
How to build a documentation site with MDX and Next.js
How to ship a landing page and dashboard with authentication in Next.js
How to launch a social app with Next.js and Supabase
Vibe Coding
Introduction to vibe coding
Set up your local dev environment
Essential tools for vibe coding
Build your first Once UI app
Common Patterns
Hero section
Static panel
Form layout
Highlighted card
Responsive stacking
Decoration layers
Dialog & modal
Toast & feedback
Tables & lists
Loading states
App shell navigation
Dashboard & charts
Chat & messaging
Auth & verification
Settings & split panels
Data filters & toolbar
Command palette
Pricing & plans
Accordion & FAQ
Media & uploads
Empty & error states
SEO, Open Graph, and structured data
Documentation code blocks with live preview
Carousels, galleries, and before/after comparisons
Date pickers and scheduling
Context menus and dropdown actions
Tags, chips, and multi-value inputs
Roadmap & kanban
Form inputs & controls
Progress, status & badges
Scrolling & feeds
Profile, avatars & identity
Social proof & logo clouds
Masonry & media grids
Table pagination, search & bulk selection
Banners & announcements
Footer layouts
Onboarding & first run
Waitlist & coming soon
Design Tips
Color & surfaces
Harness overview
Row, Column & Grid
Spacing & rhythm
Icons & buttons
Reveal & motion
Theme tokens, FOUC-free init, and runtime style controls
Tooltips and hover cards
Block updates
Block updates changelog
Agent Resources
Column, not Flex
Semantics over CSS
Typography scale
Common gotchas
Block anchors
Validate generated code
Pro block registry
Match task bundles
TrademarkTrademark
Ctrl k
Search...
Sign up
Once UI Handbook
Beginner Guides
What is Once UI?
Install & config
Page skeleton
Your first page
Build And Launch
How to launch a portfolio site that actually gets you hired
How to build a documentation site with MDX and Next.js
How to ship a landing page and dashboard with authentication in Next.js
How to launch a social app with Next.js and Supabase
Vibe Coding
Introduction to vibe coding
Set up your local dev environment
Essential tools for vibe coding
Build your first Once UI app
Common Patterns
Hero section
Static panel
Form layout
Highlighted card
Responsive stacking
Decoration layers
Dialog & modal
Toast & feedback
Tables & lists
Loading states
App shell navigation
Dashboard & charts
Chat & messaging
Auth & verification
Settings & split panels
Data filters & toolbar
Command palette
Pricing & plans
Accordion & FAQ
Media & uploads
Empty & error states
SEO, Open Graph, and structured data
Documentation code blocks with live preview
Carousels, galleries, and before/after comparisons
Date pickers and scheduling
Context menus and dropdown actions
Tags, chips, and multi-value inputs
Roadmap & kanban
Form inputs & controls
Progress, status & badges
Scrolling & feeds
Profile, avatars & identity
Social proof & logo clouds
Masonry & media grids
Table pagination, search & bulk selection
Banners & announcements
Footer layouts
Onboarding & first run
Waitlist & coming soon
Design Tips
Color & surfaces
Harness overview
Row, Column & Grid
Spacing & rhythm
Icons & buttons
Reveal & motion
Theme tokens, FOUC-free init, and runtime style controls
Tooltips and hover cards
Block updates
Block updates changelog
Agent Resources
Column, not Flex
Semantics over CSS
Typography scale
Common gotchas
Block anchors
Validate generated code
Pro block registry
Match task bundles
TrademarkTrademark
Once UIDocumentationBlog
© Once UI. All rights reserved.
Built with Aveiro
Common patterns

Onboarding & first run

Welcome dialogs, setup checklists, guided empty dashboards, and profile completion nudges.
Updated 19d ago
Footer layouts
Waitlist & coming soon
6 min · Pattern
First-run onboarding guides new users through setup with dialogs, checklist panels, and progressive disclosure. Compose with Dialog, static panels, and Button — keep one focus per step.

What this pattern covers

Onboarding appears after signup or first login:
  • Welcome Dialog — short value prop + primary action
  • Checklist panel — static Column surface with completed steps
  • Empty dashboard — Empty & error states with guided CTAs
  • Settings nudges — inline Feedback rows for incomplete profile fields
Gold references: packages/core/ai/tasks/settings.json, packages/core/ai/examples/settings.tsx, auth task packages/core/ai/tasks/auth.json.

Welcome dialog

Start with a controlled Dialog — not a full-page modal route. One headline, two sentences, one Button:
<Dialog
  isOpen={showWelcome}
  onClose={() => setShowWelcome(false)}
  title="Welcome to your workspace"
  footer={
    <Row gap="12">
      <Button onClick={startTour}>Get started</Button>
      <Button variant="secondary" onClick={() => setShowWelcome(false)}>
        Skip for now
      </Button>
    </Row>
  }
>
  <Column gap="16">
    <Text variant="body-default-m" onBackground="neutral-weak">
      Connect your repo, invite teammates, and ship your first page in under ten minutes.
    </Text>
  </Column>
</Dialog>
Persist showWelcome in user preferences or localStorage so returning users are not blocked.

Checklist panel

Replace interactive Cards with a static surface panel listing setup steps:
<Column
  fillWidth
  background="surface"
  border="neutral-alpha-weak"
  radius="l"
  padding="24"
  gap="24"
>
  <Column gap="8">
    <Heading variant="heading-strong-s">Get set up</Heading>
    <Text variant="body-default-s" onBackground="neutral-weak">
      Complete these steps to unlock your dashboard.
    </Text>
  </Column>
  <Column gap="12" fillWidth>
    {steps.map((step) => (
      <Row key={step.id} gap="12" vertical="center" fillWidth>
        <Icon
          name={step.done ? "check" : "circle"}
          size="s"
          onBackground={step.done ? "success-medium" : "neutral-weak"}
        />
        <Column gap="2" flex={1}>
          <Text variant="body-strong-s">{step.title}</Text>
          <Text variant="body-default-xs" onBackground="neutral-weak">
            {step.description}
          </Text>
        </Column>
        {!step.done && (
          <Button size="s" variant="secondary">
            {step.action}
          </Button>
        )}
      </Row>
    ))}
  </Column>
</Column>
Describe in prose: wire ProgressBar below the heading when you want a completion percentage — pass value as 0–100 based on done count.

Empty dashboard with guided CTA

When data is empty because the user has not finished setup, use onboarding copy — not generic “No data”:
Differentiate from Empty & error states: onboarding empty states assume the user is new; filtered-empty uses “Clear filters” instead.

Profile completion nudge

In Settings & split panels, highlight incomplete fields with Feedback at the top of the active section:
Dismiss the Feedback when required fields validate. Do not stack multiple Feedback rows — one nudge per section.

Multi-step vs checklist

Pattern
When
Surface
Checklist panelParallel tasks, any orderStatic Column on dashboard
Stacked dialogsSequential wizard, 3–4 stepsControlled Dialog per step
Inline empty stateSingle critical first actionCentered Column in main area
For stacked dialogs, see Dialog & modal — advance step state in the parent and swap Dialog body content. Keep footer actions consistent: Back (secondary) + Continue (primary).

Agent checklist

When generating onboarding from settings or auth task bundles:
  • Welcome Dialog is dismissible — never trap users
  • Checklist uses static panels, not Card without onClick
  • Empty dashboard copy explains the next action, not the absence of data
  • One Feedback nudge per settings section
  • Progress tracked in parent state, not inside presentational components

Write this / not this

✅ Once UI way
❌ Common mistake
Dismissible welcome DialogFull-screen blocking overlay with no skip
Checklist in surface ColumnCard rows without interaction
“Create first X” onboarding copyGeneric “No results” on first visit
One primary action per stepThree competing Buttons in welcome modal

Check yourself

  • Welcome dialog can be skipped and stays dismissed
  • Checklist steps show done vs pending with Icon affordance
  • Empty dashboard CTA matches the actual first-run flow
  • Profile nudge dismisses when fields are complete

Related

→ Dialog & modal → Empty & error states → Settings & split panels → Auth & verification
<Column fillWidth center padding="48" gap="16" maxWidth="xs">
  <Icon name="rocket" size="l" onBackground="brand-medium" />
  <Heading variant="heading-strong-s" align="center">
    Create your first project
  </Heading>
  <Text variant="body-default-s" onBackground="neutral-weak" align="center">
    Projects appear here once you import a repo or start from a template.
  </Text>
  <Button arrowIcon>New project</Button>
</Column>
<Column gap="24">
  <Feedback
    title="Complete your profile"
    description="Add a photo and display name so teammates recognize you."
    variant="info"
  />
  {/* profile form fields */}
</Column>