The Anatomy of a Good Empty State: 6 Patterns That Guide the Next Action
- Three empty state types: first-run, cleared, error-empty, each needs different copy
- One primary action rule: never give an empty screen two equal buttons
- Copy teaches, never apologizes: replace "No items found" with a next step
- 6 patterns I ship across every RAXXO interface
Most empty states are accidents. Nobody designs them, so they default to a gray "No data" line and a sad icon. I treat them as the cheapest onboarding I will ever build, because a person sees the empty state before they see anything full.
Why Empty States Are Onboarding in Disguise
The first screen a new user sees is almost always empty. No projects, no orders, no saved items. That is not a failure mode. That is the actual product introduction, and it happens at the exact moment the person is deciding whether to keep going.
I tracked this on one of my dashboards. Out of 100 new accounts, 38 hit an empty list within the first 20 seconds. If that screen just says "No projects yet," I am wasting the most attentive moment a user will ever give me. They are not bored yet. They are not frustrated yet. They are looking for the next thing to do.
So I split empty states into three kinds, and I never let one template cover all three.
The first is first-run empty. The user has never had data here. This is pure onboarding. The job is to explain what this space is for and hand them one obvious action.
The second is cleared empty. The user had data and finished it. An inbox at zero, a task list completed, a cart emptied after checkout. This one should feel like a small reward, not a void. "You are all caught up" beats "No messages" every time.
The third is error-empty. Something failed. The list is empty because a request timed out or a filter returned nothing. This needs a different tone again, because the user did not cause it and a cheerful illustration here feels mocking.
When I started labeling every empty screen with one of these three tags before writing a single word of copy, my interfaces got noticeably less confusing. The same gray box was doing three jobs badly. Now each job gets its own treatment. The structural lesson is the same one behind any good system: name the state before you style it, the way I name component states in Claude Blueprint before I write a line of markup.
Pattern 1 and 2: The Single Primary Action Rule
Here is the rule I break the least: an empty state gets exactly one primary action. One button that looks like a button. Everything else is text or a secondary link.
I learned this the hard way. An early version of a project screen had three buttons of equal weight: "Create project," "Import data," and "Watch tutorial." All three were blue. All three were the same size. New users clicked none of them at a rate that embarrassed me. When three options carry equal visual weight, the brain treats the choice as work, and work at minute zero is where people leave.
I cut it to one blue button: "Create your first project." The other two became a single line of gray text underneath: "or import from a file." The number of people who took any action inside the first session jumped enough that I stopped second-guessing the rule.
Pattern 1 is the single primary action. Pattern 2 is the supporting line. The supporting line exists for the 15 percent of users who do not want the obvious path. You do not hide the import option. You demote it. The visual hierarchy does the teaching: this is what most people do, and here is a quieter door if you are not most people.
A concrete checklist I run on every empty state now:
- Exactly one element styled as a primary button.
- That button's label is a verb plus the object ("Add a product," not "Get started").
- Any alternative path is text-weight, not button-weight.
- No more than two total clickable things in the whole empty area.
That last point matters. I counted the clickable elements on one cluttered empty screen and found seven, including a help icon, two nav crumbs, and a settings gear. Seven targets on a screen with zero content. I stripped it to two. The button and the alternative link. Less to scan means faster decisions, and a faster first decision is the entire game on a brand-new account.
Pattern 3 and 4: Copy That Teaches Instead of Apologizing
The default empty-state copy is an apology. "No results found." "Nothing here yet." "Sorry, no items." Apology copy treats the empty screen as a problem the user must forgive. Teaching copy treats it as the next lesson.
Pattern 3 is the teaching headline. Instead of describing the absence, describe the capability. Bad: "No automations." Good: "Automations run tasks for you while you sleep." The second version tells a brand-new user what the feature even does, which the empty screen is the perfect place to explain because there is nothing else competing for the space.
I rewrote 11 empty-state headlines across one app using this single swap. Describe what the thing does, not what is missing. For a saved-searches feature I went from "No saved searches" to "Save a search to get alerts when new listings match." The word count went up by six. The clarity went up far more, because a new user genuinely did not know that saved searches triggered alerts. The empty state taught them.
Pattern 4 is matching tone to state type, which ties back to the three categories. First-run copy is instructional and warm. Cleared copy is congratulatory and brief. Error-empty copy is plain and honest, with a retry action.
Here is the same screen, a notifications list, written three ways:
- First-run: "Notifications show up here when something needs you. Turn on alerts to start."
- Cleared: "You are all caught up. Nice."
- Error-empty: "We could not load notifications. Retry, or check back in a minute."
Same empty list, three completely different messages, because the user arrived at the empty state for three completely different reasons. The error version gets the retry button. The cleared version gets nothing clickable at all, because the user just finished and does not need a task. The first-run version gets the one primary action.
The thing I keep relearning: copy in an empty state is not decoration around the real UI. In an empty state, the copy IS the UI. There is nothing else on the screen, so every word is load-bearing. If you want the deeper context on writing interface copy that does work, Claude Blueprint walks through how I prompt for it consistently.
Pattern 5 and 6: Illustration Weight and the Cleared-State Reward
Pattern 5 is illustration restraint. A big custom illustration on an error-empty state reads as tone-deaf. The request failed and you are showing me a smiling cartoon. I keep illustrations for first-run and cleared states only, and even there I keep them small.
I generate these in batches with Magnific when I want a consistent style across a dozen empty screens, then downscale hard. A 1200px hero illustration on an empty list is the wrong weight. It pulls attention away from the one action I want the user to take. I cap empty-state art around 160px wide. The button stays the loudest thing on screen. The art supports, it does not headline.
There is a measurable cost to heavy illustrations too. One first-run screen shipped with a 480KB animated graphic that delayed the primary button paint by most of a second on a mid-range phone. The button is the point. Delaying the button to show art is the tail wagging the dog. I swapped it for an inline SVG under 8KB and the button appeared instantly.
Pattern 6 is treating the cleared state as a reward, not a void. This is the one most products miss. When a user clears their inbox or finishes every task, the screen goes empty, and a lazy design shows the same "No items" message it would show a confused first-run user. That is a wasted moment of genuine satisfaction.
Give the cleared state a small payoff. A short congratulatory line. A subtle checkmark. Maybe a count of what they just finished ("12 tasks done today"). I added a one-line cleared message to a task app and the number of users who came back the next day to clear it again went up, because finishing felt like something instead of nothing.
If a cleared state is a natural moment of accomplishment, it is also a natural moment to suggest the next loop. Not a hard sell. A gentle "Schedule next week's posts?" works when someone just cleared their queue. I route social actions like that through Buffer so the cleared state becomes a soft on-ramp to the next session rather than a dead stop. The rule stays intact: one primary action, even in the reward state.
Bottom Line
Empty states are not edge cases. They are the first screen, the finished screen, and the broken screen, and each one is a chance to either guide someone or lose them. Label every empty area as first-run, cleared, or error-empty before you write a word. Give it exactly one primary action. Write copy that teaches what the feature does instead of apologizing for what is missing. Keep illustrations small enough that the button stays the loudest thing on screen. And treat a cleared state as a reward, because the user earned it.
I run these six patterns as a checklist on every interface I ship now, and the gray "No data" box has basically disappeared from my work. The screens that used to feel like dead ends now point somewhere. If you want the full system I use to prompt for interface copy and component states consistently, Claude Blueprint is where I keep it. Start with your most-seen empty screen and rewrite the headline first. That one swap usually pays for itself.
This article contains affiliate links. If you sign up through them, I may earn a small commission at no extra cost to you. (Ad)
Back to all articles