Reveal loaded content

Slide the skeleton down and out, and the content up and in.

Next.js docsnextjs.org
In motion design, vertical direction encodes hierarchy. Content sliding up communicates arrival. Content sliding down communicates departure.
Suspense revealsRead docs ↗

From vercel-react-view-transitions, implementation.md.

Skeleton to content

Press Load and watch the swap.

Instant swapBad
<Suspense fallback={<Skeleton />}>
Exit down, enter upGood
exit="slide-down" · enter="slide-up"
<Suspense
  fallback={
    <ViewTransition exit="slide-down">
      <Skeleton />
    </ViewTransition>
  }
>
  <ViewTransition enter="slide-up" default="none">
    <AsyncContent />
  </ViewTransition>
</Suspense>

Keep the title outside

Load again and watch the title.

Title in bothBad
fallback and content both render it
Title above SuspenseGood
<h1> renders once
<h1>{title}</h1>
<Suspense fallback={<BodySkeleton />}>
  <Body />
</Suspense>

Why it matters, pros and cons

Why it matters

The skeleton leaves fast so it doesn't compete. The content arrives slower so you register it. Down reads as leaving, up as arriving.

Pros

  • Loading reads as a handoff, not a pop.
  • Works the same for loading.tsx.
  • Coexists with page slides; they fire at different moments.

Cons

  • Reveals carry no type; use plain string props.
  • Anything in both fallback and content dips.
  • Scroll is frozen while it plays; keep it short.