webdevpuneet.com

Empty State with Sample Data Toggle — Free Dashboard UI (HTML/CSS/JS)

Empty State with Sample Data Toggle · Cards · Plain HTML, CSS & JS · Live preview

CategoryCards

Copy & paste

Source Code

<div class="esd-card">
  <div class="esd-empty" id="esdEmpty">
    <div class="esd-illustration">
      <svg viewBox="0 0 64 64" fill="none" stroke="currentColor" stroke-width="1.6">
        <rect x="10" y="16" width="44" height="34" rx="4"/>
        <path d="M10 26h44"/>
        <path d="M20 34h10M20 40h16"/>
        <circle cx="46" cy="42" r="9" fill="#0f1420" stroke="#3b82f6"/>
        <path d="M46 38v8M42 42h8" stroke="#3b82f6"/>
      </svg>
    </div>
    <h3>No projects yet</h3>
    <p>Create your first project to start tracking tasks, or preview what it looks like with sample data.</p>
    <div class="esd-actions">
      <button type="button" class="esd-btn-primary" id="esdCreate">+ Create project</button>
      <button type="button" class="esd-btn-ghost" id="esdLoadSample">Load sample data</button>
    </div>
  </div>

  <div class="esd-populated" id="esdPopulated" hidden>
    <div class="esd-populated-head">
      <span class="esd-sample-tag">Sample data</span>
      <button type="button" class="esd-btn-ghost esd-clear" id="esdClear">Clear sample data</button>
    </div>
    <div class="esd-rows" id="esdRows"></div>
    <button type="button" class="esd-btn-primary esd-full-width" id="esdCreateFromSample">+ Create your first real project</button>
  </div>
</div>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Two-state toggle
Empty and populated-preview states are mutually exclusive and simple to reason about.
Clearly tagged sample data
A persistent "Sample data" label prevents confusing fake rows for real ones.
One-click reset
"Clear sample data" always sits next to the tag, ready to return to empty.
CTA available from both states
Users can start creating from the empty state or right after previewing the sample.
Realistic sample content
Varied statuses and metadata sell the feature better than lorem-ipsum rows.
No partial states
hidden-attribute toggles guarantee exactly one view renders at a time.
Illustration + copy pairing
A lightweight inline SVG keeps the empty state visually inviting without an image asset.
Easy to theme
Swap the illustration, copy, and sample data for any resource type.

About this UI Snippet

Empty State with Sample Data Toggle — Let New Users Preview Before They Commit

Screenshot of the Empty State with Sample Data Toggle snippet rendered live

A first-run empty state has one job: get the user to create their first real thing. But a blank "No projects yet" screen with a single button asks for commitment before the user has any idea what the feature actually looks like in use. This snippet solves that with a secondary "Load sample data" action that swaps the empty state for a small, clearly-labeled preview of a populated view — letting a new user see the feature working before they invest effort in setting it up themselves.

Two states, one toggle

The card has exactly two states — an empty illustration-and-CTA view, and a populated preview with 2–3 fake rows — controlled by simple hidden attribute toggles in showSample() and showEmpty(). There's no partial or ambiguous state in between; either the empty state or the sample view is visible, never both, which keeps the interaction easy to reason about and easy to test.

Clearly marked as a sample

The populated view carries a persistent "Sample data" tag in its header so a user can never mistake the preview rows for their real, saved data — a mistake that would be confusing and potentially destructive if they later tried to "delete" one of the fake rows. A "Clear sample data" action sits right next to that tag, so returning to the empty state is always one click away and clearly labeled as the inverse of "Load sample data."

A second path back to creation

The populated preview ends with its own "Create your first real project" button — because seeing the feature in action is often exactly what convinces a hesitant user to commit. Rather than making them clear the sample data first and re-find the original CTA, the creation action is available directly from the state that sold them on it.

Realistic but obviously fake data

The sample rows use varied, plausible content (different statuses, task counts, and relative timestamps) rather than lorem-ipsum placeholders, because the whole point is to demonstrate what a *real*, in-use dashboard looks like — a grid of "Item 1, Item 2, Item 3" wouldn't sell the feature the way "Mobile app v2 · 11 tasks · at risk" does.

Where it fits

Pair it with an empty state for simpler no-CTA-needed cases, an onboarding checklist widget for the broader first-run flow, or empty-state-ai-suggestions for an AI-assisted variant of the same "help them get started" problem.

Customizing it

Swap the illustration and copy for your own resource type (contacts, invoices, campaigns), adjust the sample row count, or auto-clear the sample data after a set time or on the user's first real save so it never lingers past its usefulness.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSA "No projects yet" empty state renders with two actions.
  2. 2
    Click Load sample dataThe empty state swaps for 3 sample project rows, tagged "Sample data."
  3. 3
    Try the sample-view CTA"Create your first real project" is available directly from the preview.
  4. 4
    Click Clear sample dataThe view returns cleanly to the original empty state.
  5. 5
    Wire up the create actionsReplace the alert() calls with your real project-creation flow.
  6. 6
    Swap in your resourceAdjust the illustration, copy, and sample rows for your own data type.

Real-world uses

Common Use Cases

Project and task dashboards
Preview a populated project list before a user commits to creating anything, so they understand what the feature will look like when full.
CRM and pipeline tools
Show sample deals or contacts so a new user can see the value of the product, with a persistent Sample data tag preventing confusion with real records.
Analytics previews before data
Pair with a skeleton dashboard loading state, so empty, loading and populated views are all designed.
Onboarding flows
Combine with an onboarding checklist widget so the first step can be exploring sample content or creating a real item.
Table-based tools
Use the same toggle in front of a filterable table or editable table, with a one-click Clear sample data button beside the tag.
Related: Now Playing Mini Player
See the Now Playing Mini Player for a related cards pattern worth pairing with this one.

Got questions?

Frequently Asked Questions

The populated preview always carries a visible "Sample data" tag in its header, distinct from any real content styling, and a "Clear sample data" button sits directly next to it — so a user always knows they're looking at a preview and always has an obvious, adjacent way back to the empty state.

In this snippet the sample rows are display-only (no edit or delete controls), which is the safest default. If you add interactivity to sample rows, keep the "Sample data" tag visible at all times and consider disabling destructive actions specifically on sample content.

Seeing the feature working with realistic content is often what convinces a hesitant user to invest the effort of creating their first real item — so the CTA is placed directly in the state that just sold them on the feature, rather than requiring them to clear the sample data first and hunt for the original button.

Generally no — an explicit toggle keeps the user in control and avoids ambiguity about whether what they're seeing is real. If you want a zero-click preview, consider auto-loading it only on a true first visit and pairing it with an even more prominent "this is sample data" treatment.

Track a single boolean (e.g. showSample) in component state instead of toggling hidden attributes directly, and conditionally render the empty or populated block based on it. The SAMPLE_ROWS array and its rendering map over directly into JSX or a template loop.