Skeleton

Skeleton

Markdown

A visual placeholder that preserves content shape while asynchronous data is loading.

Use Skeleton when loading content has a predictable final layout. Use Spinner when the eventual shape is unknown or the wait is tied to one compact action.

Profile placeholder

Installation

$npx shadcn@latest add @patchui/skeleton

The copied source is available in the registry JSON. The canonical implementation lives in packages/react/src/components/skeleton.tsx.

Usage

<div aria-busy="true" aria-label="Loading profile">
  <div className="flex items-start gap-4">
    <Skeleton shape="pill" width={40} height={40} />
    <div className="flex flex-1 flex-col gap-2">
      <Skeleton height={16} width="35%" />
      <Skeleton height={16} width="70%" />
    </div>
  </div>
</div>

Match placeholder dimensions closely to the final content so loading does not create avoidable layout shifts.

Examples

Reveal content

Use show when the same component boundary should switch from its placeholder to loaded children.

Reveal content

API reference

PropTypeDefaultDescription
width / heightnumber | string-Sets pixel or CSS-length dimensions.
shape"rounded" | "pill" | "squared""rounded"Selects radius-6, full-radius, or square geometry.
animatedbooleantrueEnables the token-based pulse animation.
show / childrenboolean / ReactNodetrue / -Renders the skeleton while true and its children while false.

Classes and inline style can further refine geometry, but explicit width, height, and shape keep common placeholders readable in source.

Accessibility

  • Skeleton is decorative and hidden from assistive technology.
  • Put aria-busy="true" on the content region being updated, then remove it when loading completes.
  • Add a concise status message when people need confirmation that loading is in progress; do not create one live region per placeholder.
  • Pulse animation stops under reduced-motion preferences.
  • Preserve the final reading and tab order when content replaces the placeholders.