Skip to content

Skeleton Handoff

Skeleton Handoff measures matching loading blocks and real content, then uses GSAP Flip to move each block into place while revealing the content. Cached results render directly, short loads skip the skeleton, and refetches crossfade without reversing the handoff.

Dependencies

gsap@gsap/reactclsxtailwind-merge

Interaction

A root-level handoff pairs the first block and target for each data-handoff-id. Flip.fit animates each solid block to its target rectangle while real content fades in unscaled. The root height eases once to the measured content height, then all temporary inline animation styles are removed.

Props

PropTypeDescription
status"loading" | "ready" | "error"Controls the skeleton, handoff, and error states.
skeletonReact.ReactNodeSkeleton markup containing HandoffBlock elements.
childrenReact.ReactNodeContent rendered when ready and measured during handoff.
durationnumberTravel duration in seconds.
staggernumberDelay between blocks, in seconds.
skipBelownumberDelay in milliseconds before the skeleton becomes visible.
loadingLabelstringPolite live-region text while data is loading.
readyLabelstringPolite live-region text when data becomes ready.
errorLabelstringVisible alert text when the request fails.
onHandoffStart() => voidCalled when a loading-to-ready handoff begins.
onHandoffComplete() => voidCalled after the handoff animation completes.
classNamestringAdditional classes for the root element.
HandoffBlock{ id: string; className?: string; as?: React.ElementType }Creates a solid skeleton block with a matching identifier.
HandoffTarget{ id: string; className?: string; as?: React.ElementType; children: React.ReactNode }Marks real content that matches a skeleton block.

MIT License. Free to use in personal and commercial projects. Built for Peel UI.