On this page
An empty content area is still an interface. It needs to tell people whether they have not created anything yet, whether their filters excluded everything, or whether the application could not retrieve existing information. Those situations may occupy the same rectangle, but they should never share the same generic message.
Start with a state inventory
Before designing an illustration, list every reason the region can be empty. Include initial loading, a new account, a successful search with zero matches, a failed request, missing permission, and an intentionally completed queue. Give each a distinct name in the component specification. This state inventory prevents a convenient fallback from becoming misleading product behavior.
Use the contrast checker to test explanatory text, secondary actions, and button labels against the actual empty-state surface. Enter the foreground and background colors used in the design, not approximate swatches. Empty states often get visually muted until their most important instructions become difficult to read.
An empty region should preserve the page's purpose. Keep the section heading, relevant controls, and orientation cues where they normally appear. The design resources can help with the surrounding composition, but the central question remains practical: what can someone do from here?
Design first-use states around one useful action
A first-use state explains what belongs in the space and helps someone create the first meaningful item. For a projects screen, try a heading such as “No projects yet,” followed by “Create a project to organize files and share progress.” The primary button can simply say “Create project.” Each line has a different job.
Avoid describing every feature available after setup. A short description, one primary action, and an optional example usually provide enough orientation. If importing existing work is common, offer “Import projects” as a secondary action rather than hiding it in onboarding copy. Prioritize based on the actual entry paths the product supports.
Show a sample only when it clarifies the expected output. A realistic preview of one project row may be more useful than a decorative rocket. Clearly label sample content and explain whether it can be edited or deleted. Do not make an example look like user data that has mysteriously appeared.
Respect permission-aware actions. A viewer who cannot create projects should not see a disabled creation button without explanation. Instead, state who can add projects and offer an available next step, such as contacting the workspace owner. A new account and a restricted account are different states even if both contain zero items.
Help people recover from no results
A no-results state means the request succeeded but nothing matched. Preserve the query and active filters so the reason remains visible. “No invoices match these filters” is more accurate than “You have no invoices” when the underlying collection contains hundreds of records.
Provide a recovery action that changes the condition. “Clear filters” is useful when filters caused the problem; “Try again” generally is not. If there is a search query as well as filters, specify whether the reset clears both. Prefer separate actions when users may want to retain part of their search.
Use concrete hints rather than blaming the user. Suggest a broader date range, a shorter search term, or a different status only when those controls actually exist. Avoid asserting that a spelling error occurred unless the system can substantiate it. The Nielsen Norman Group guidance on error messages is also useful for writing clear, constructive recovery copy.
Keep search and filter controls available above the message. Replacing the entire page with a large illustration forces people to rediscover controls. On mobile, do not push the reset action below an oversized image. A modest icon and two lines of text may solve the problem better than a full-screen composition.
Distinguish failures from genuine emptiness
An error empty state should not claim that data does not exist. Say “We couldn't load invoices” and explain what remains possible. If existing rows can stay visible during a refresh failure, retain them and place an error notice nearby instead of replacing useful information with an empty panel.
Offer a retry action when repeating the request could help. Preserve filters, query, and unsaved local input. A retry that resets the page turns a temporary network issue into lost work. If the problem is a missing permission or an expired session, the appropriate action is different: request access or sign in.
Use this rendering sketch to make the decision order explicit. It is not a complete data-fetching implementation; the key is preventing an unsuccessful response from masquerading as a successful empty collection.
function getListState({ status, items, hasConstraints }) {
if (status === "loading") return "loading";
if (status === "error") return "error";
if (status !== "success") return "idle";
if (items.length > 0) return "populated";
return hasConstraints ? "no-results" : "first-use";
}In production, add explicit permission and completed-work states where needed. A zero-item response does not by itself prove first use; an established workspace may simply have no current items. The guide to asynchronous UI states provides useful adjacent implementation context.
Keep diagnostic identifiers available without exposing raw stack traces. Support details belong in a secondary disclosure or copyable reference, not in the headline. Do not promise a recovery time unless the application has dependable information to support it.
Specify layout, announcements, and transitions
Use a stable content region so loading, empty, and populated states do not constantly relocate the toolbar. Start with roughly 24–32 pixels of panel padding and a readable text width around 40–55 characters. Adjust these working values to the surrounding component rather than forcing every empty state into a hero layout.
Keep the hierarchy consistent: short heading, explanation, primary action, then optional help. Use an illustration only if it adds meaning. For additional interface checks, see the practical accessibility guide and the WAI button pattern for action behavior.
When a search finishes, a polite results announcement may help communicate the change without moving keyboard focus. The WCAG status messages explanation covers this distinction. Avoid automatically focusing a message after every keystroke or repeatedly announcing decorative content.
Review the transition checklist with real interactions: create the first item, delete the last item, clear all filters, lose connectivity, retry, and switch permissions. Verify that each outcome uses accurate copy and that focus remains somewhere useful. A polished screenshot proves little if the interface cannot leave its empty state cleanly.
Key takeaways
- Name each empty condition before designing the shared component.
- Give first-use screens one clear route to meaningful content.
- Preserve search context and provide precise reset actions.
- Never present a failed request as a successful zero-item result.
- Test state transitions, readable copy, and available actions together.
Reach designers & developers at work
Put your product next to the tools people use every day. One sponsor per placement, no tracking pixels.
Become a sponsor