Async Content & Error State
One place for every state of async data (idle, loading, loaded, empty, error), with skeletons that don't flicker and errors that always offer a way out.
Click “Load members” to start.
Import
Install from npm, copy the source into your project with @yugen-ui/cli or the shadcn CLI, or import directly when working in this repo.
// npm install yugen-uiimport { AsyncContent, ErrorState, type AsyncStatus } from "yugen-ui";Variants
Each tile is a standalone example: hover to copy, or press Code to see the source.
Connection lost
Couldn't load comments. Check your network and try again.
ErrorState with retry
If onRetry returns a Promise, the Retry button shows a spinner until it settles; focus stays on the button.
Couldn't load the chart
This week's data isn't available yet.
Compact ErrorState
size="small" for cards, panels and list rows.
No results
Try a different keyword or remove some filters.
Custom empty state
Empty isn't an error: say why there is nothing here and suggest a next step.
Usage
- Keep empty and error clearly apart. Empty is a valid result; an error needs a way out.
- An error says what happened and offers a retry right there.
- Pass a skeleton that matches the layout of the real content.
- Don't leave a blank area on an error or when there is no data.
- Don't use technical messages (error codes, stack traces) as the title.
- Don't use role="alert" for first-load errors in many regions at once. They would all be announced in a burst.
Props
| Prop · Type | Default | Description |
|---|---|---|
| status"idle" | "loading" | "success" | "error" | "empty" | Default: — | State to render. |
| childrenReactNode | () => ReactNode | Default: — | Content on success; the function form is only called on success. |
| skeletonReactNode | Default: SkeletonText, 3 lines | Shown while loading (after delay). |
| errorReactNode | ({ retry, retrying }) => ReactNode | Default: ErrorState | Replaces the error UI. |
| empty / idleReactNode | Default: — | Empty UI (Empty by default) / not-yet-loaded UI (nothing by default). |
| onRetry() => void | Promise | Default: — | Passed to the Retry button of the default ErrorState. |
| delay / minDurationnumber | Default: 300 / 500 | How long to wait before showing the loader, and the minimum time it stays once shown (ms). See useSpinDelay. |
| loadingLabelstring | Default: "Loading…" | Text announced to screen readers when the skeleton appears. |
| ErrorState | Default: — | Error content; the default text is in Vietnamese. |
| ErrorState | Default: — | Retry button; a Promise or retrying puts the button in its loading state. |
| ErrorState | Default: — | Secondary action (Report a problem, Go back…). |
| ErrorState | Default: "default" · "medium" | alert adds role="alert"; small is a compact single line. |
Messages
Text built into the component: labels, aria-labels, screen reader announcements.
English by default. Change it with the messages prop of YugenProvider, by the namespace below; messagesVi has the Vietnamese set. See Interface language.
messages.errorState
| Key · Type | Default (English) | messagesVi |
|---|---|---|
| titlestring | Default (English)"Couldn't load content" | messagesVi"Không tải được nội dung" |
| descriptionstring | Default (English)"Something went wrong while connecting to the server. Check your connection and try again." | messagesVi"Đã có lỗi khi kết nối tới máy chủ. Kiểm tra mạng rồi thử lại." |
| retrystring Nút thử lại (khi có | Default (English)"Retry" | messagesVi"Thử lại" |
messages.asyncContent
| Key · Type | Default (English) | messagesVi |
|---|---|---|
| loadingstring Câu đọc cho trình đọc màn hình khi khung xương hiện. | Default (English)"Loading…" | messagesVi"Đang tải…" |
| emptyTitlestring Tiêu đề / mô tả của trạng thái rỗng mặc định. | Default (English)"No data yet" | messagesVi"Chưa có dữ liệu" |
| emptyDescriptionstring | Default (English)"New content will appear here." | messagesVi"Khi có nội dung mới, chúng sẽ xuất hiện ở đây." |