| name | Empty & Error States |
| description | ENSURE every async UI component handles all four states: Loading, Empty, Error, Success. Prevent blank screens, stuck spinners, confusing empty states, and full-page crashes from one component's error. Trigger: "handle (the|the) loading state", "what if there's no data?", "handle API errors (on|in the) frontend", "polish the UI".
|
| category | product-polish |
| version | 3.0.0 |
| last_updated | 2026-06-28T00:00:00.000Z |
| stacks | ["React 19.2","Vue 3","Next.js 16"] |
| triggers | [{"pattern":"(handle|fix|add) (the|a) loading (state|indicator)","action":"ADD skeleton matching layout geometry"},{"pattern":"(handle|what if) (there's|there is) no data","action":"ADD Empty state with CTA"},{"pattern":"(handle|fix) (api|server) errors (on|in) the frontend","action":"ADD Error state with retry button"}] |
| related_skills | ["component-architecture-patterns","dashboard-information-architecture","performance-budgets-and-cwv"] |
Empty: Loading, and Error States
IDENTIFY: When to Activate
Activate when building ANY component or page that:
- Fetches data asynchronously
- Depends on user-generated content (may be empty)
- Calls an external API (may fail)
- Renders dynamic content based on server response
CORE PATTERN: Four States, Always Checked in This Order
if (isLoading) → Show skeleton matching layout geometry
if (error) → Show error message + retry button
if (!data || data.length === 0) → Show empty state with CTA
else → Show success state (actual content)
EXECUTE: Instructions
Step 1: Loading State: Skeleton Screens ALWAYS, Spinners NEVER
Skeleton screens match the final layout shape:
function DashboardSkeleton() {
return (
<div className="grid gap-4 md:grid-cols-3">
{Array.from({ length: 6 }).map((_, i) => (
<div key={i} className="h-32 rounded-lg bg-muted animate-pulse" />
))}
</div>
);
}
function TableSkeleton() {
return (
< =>
{/* header */}
{Array.from({ length: 5 }).map((_, i) => (
))}
);
}