Skeleton
A grey shape with a soft shimmer that stands where content will appear while it loads.
ui.skeleton
components/ui/skeleton.tsxUse case
Use skeletons while a page's data comes from the server and you know its shape: a client's row with its avatar and two lines, a card's figure, the first rows of the invoices table. Drawn in the same sizes as the real content, the page does not jump when it lands.
Use it when
- A list, a table or a card loading for the first time
- A record's page while its data is read
- Any wait where the shape of the result is known
Use something else when
- A short wait with no shape (saving, sending): Spinner
- A task with a known amount done: Progress
- The data came back empty: Empty state
Examples
Code
Import
import { Skeleton } from "@/components/ui/skeleton"Usage
export function ClientRowSkeleton() {
return (
<div className="flex w-full max-w-sm items-center gap-3 rounded-[20px] bg-background p-4 shadow-(--shadow-rest)">
<Skeleton className="size-10 rounded-full" />
<div className="grid flex-1 gap-2">
<Skeleton className="h-3.5 w-2/3" />
<Skeleton className="h-3 w-1/2" />
</div>
</div>
)
}Rules
- Mirror the real layout: the same sizes and places as the content (a round size-10 for a face, h-3.5 and h-3 lines at 2/3 and 1/2 width).
- Size and shape come from className; the corner is 8px by default, rounded-full for a face.
- Keep the real frame (the card, the row) and put the skeletons inside it.
- Never for a button's wait: Button's loading prop does that.