SaaS · Saas

SaaS User Onboarding — A Field Guide

The in-product UX mechanics that actually drive activation: empty states that teach instead of apologize, checklists that don't nag, and disclosure that hides complexity until it's earned.

John Kihiu12 min read

Most SaaS onboarding advice is strategy: which users to target, when to show pricing, how to sequence emails. This isn't that. This is about the four or five UX mechanics that actually happen on screen in the first session — the empty state, the checklist, the progressive disclosure, the moment something first works — because that's where activation is won or lost, and it's the part most teams under-invest in relative to the acquisition funnel that got the user there in the first place.

Empty states that teach instead of apologize

The default empty state is a gray box with "No data yet" and maybe a button. That's a wasted screen. The first time a user sees a table, a dashboard, or a workspace with nothing in it, that screen is doing one job: showing them what it will look like once it's not empty, and giving them exactly one action to get there. A good empty state has a short sentence describing the end state ("Your first project will show up here"), a visual approximation of populated content — even a grayed-out mockup — and a single primary button that starts the shortest path to filling it in. Multiple competing buttons on an empty state is a sign the team hasn't decided what the first action actually is.

Test the empty state, not just the happy path

Empty states are the screen every new user sees and the screen teams QA least, because by the time you're testing internally your account already has data. Log in with a genuinely fresh account before every release and look at every list, table, and dashboard with nothing in it.

Setup checklists that guide without nagging

A setup checklist works when it's short, ordered by dependency, and disappears once it's done. It stops working the moment it becomes a permanent fixture nagging a user who has already gotten value from the product without finishing item 4. The pattern that holds up: 3-5 items, each one unlocked or made obviously relevant by the item before it, progress shown as a fraction or bar rather than a vague percentage, and a way to dismiss it that the product respects — if a user closes the checklist, don't resurrect it on every page load.

JSX · CHECKLIST COMPONENT
function SetupChecklist({ steps, onDismiss }) {
  const done = steps.filter(s => s.complete).length;
  if (done === steps.length || steps.dismissed) return null;

  return (
    <div className="checklist">
      <div className="checklist-header">
        <span>{done} of {steps.length} done</span>
        <button onClick={onDismiss}>Dismiss</button>
      </div>
      {steps.map(step => (
        <a key={step.id} href={step.href}
           className={step.complete ? 'done' : 'pending'}>
          {step.label}
        </a>
      ))}
    </div>
  );
}

Progressive disclosure: hide the 80% that isn't needed yet

Every mature SaaS product accumulates settings, edge-case options, and power-user features that a brand-new account has no use for and no context to evaluate. Progressive disclosure means the first-run experience shows the smallest set of controls that produces a working result, and everything else — advanced filters, bulk actions, integrations, permission granularity — appears only when the user reaches a point where they'd plausibly need it. The mistake is confusing this with hiding things behind an extra click for its own sake; the goal isn't fewer options visible, it's fewer options visible before the user has the context to make sense of them. A settings panel with forty toggles on day one teaches the user that this product is complicated before they've learned it's useful.

Engineering the first activation moment

Activation is usually defined at the account or cohort level — "70% of users who do X in the first week retain" — but from the UX side it's a specific moment on a specific screen: the first chart that renders with real data, the first automated email that goes out, the first teammate who accepts an invite. That moment needs to be visually distinct from the fifty times it happens afterward — a brief animation, a confirmation toast, a "nice, that's your first one" microcopy — because the user needs external confirmation that what they did actually worked and mattered. Silence at that moment reads as ambiguity, and ambiguous success feels the same as failure to someone still deciding whether this product is worth their time.

Don't gate the activation moment behind a modal

Celebrating success with a modal that requires a click to dismiss adds friction to the exact moment you want frictionless. A toast, an inline badge, or a state change in the UI the user is already looking at works better than anything that interrupts.

When checklists and disclosure work against each other

These patterns can conflict: a setup checklist that says "configure your team's permissions" is pointing straight at the advanced settings panel that progressive disclosure is supposed to be hiding. The fix isn't to drop one pattern, it's to make the checklist item itself the disclosure trigger — clicking "configure permissions" from the checklist should reveal exactly the permissions UI in context, not dump the user into a fully-expanded settings page where the one setting they need is one of thirty. Treat every checklist item as a deep link into a temporarily-disclosed piece of UI, not a signpost to go find something.

Wrapping up

None of these patterns are novel — empty states, checklists, and progressive disclosure have been onboarding staples for a decade. What separates a product that activates well is treating them as one connected system rather than separate features: the empty state hands off to the checklist, the checklist reveals disclosure in context, and the whole thing ends at a clearly marked first win. Get that chain right and most of the "onboarding strategy" conversations upstream get a lot easier to have.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.