Next.js

Verified against Claude Code · 2026-07-21

Design loading UI so one slow query doesn't block a whole page from painting

Places loading.tsx and granular Suspense boundaries around a page's actual data dependencies, so fast content streams in immediately instead of waiting on the slowest fetch.

Claude CodeCursor 2.1v0 by Vercel

The prompt

Ready to copy — highlighted parts are example details you can swap.

<context>
Page and its data dependencies, roughly in order of how fast each one resolves: user profile header (fast, cached), order history table (medium), real-time inventory sync status (slow, external API)
The slowest data source on this page: The inventory sync status — it calls a third-party API with ~2s typical latency
</context>

<task>
Design the loading UI for this page using route-level loading.tsx and granular Suspense boundaries, so the page streams in as each piece of data resolves instead of showing one full-page spinner until the slowest fetch finishes.
</task>

<requirements>
- Use loading.tsx at the route segment level for the initial navigation fallback — this automatically wraps the segment in a Suspense boundary, so it should show a skeleton that roughly matches the eventual layout, not a generic spinner.
- Identify which pieces of the page are independent of each other's data (don't need to wait on one another) and wrap each in its own Suspense boundary with its own fallback, so they can resolve and stream in on their own schedule. The slowest data source above should never be awaited at the top of the page component in a way that blocks everything else from rendering.
- Give each Suspense boundary a fallback that's sized and shaped like the real content (a skeleton with matching dimensions), not a generic centered spinner that causes a layout jump when the real content swaps in.
- If a section legitimately needs to wait on another (e.g. a detail panel that needs to know which item was selected first), don't force it into a parallel Suspense boundary — nest it, or leave it sequential, and say so explicitly rather than parallelizing something that has a real dependency.
- Note where this interacts with caching: a Suspense boundary around a component doesn't change whether that component's data is cached — that's a separate decision — it only changes when the browser sees the result.
</requirements>

<output_format>
The page's Suspense structure (as a component tree, fallback components sketched not fully styled), plus a one-line note on which sections are truly independent vs. genuinely sequential.
</output_format>
Customize the highlighted detailsoptional — the prompt above already works

Why this works

The mechanism worth naming explicitly is that loading.tsx isn't just a fallback file — it automatically wraps the whole route segment in a Suspense boundary, which is why a single loading.tsx at the page level still produces an all-or-nothing spinner if nothing inside the page has its own, more granular boundaries. The fix is structural, not decorative: identifying which sections are actually independent and giving each its own Suspense means the fast profile header can paint immediately while the slow third-party inventory check is still pending, instead of the whole page waiting on the slowest promise in the tree. Explicitly separating 'independent — parallelize' from 'genuinely sequential — don't force it' stops the model from over-applying Suspense boundaries to sections that have a real data dependency on each other, which just adds waterfall complexity without the streaming benefit. And calling out that Suspense affects when content is shown, not whether it's cached, prevents conflating two decisions that are easy to blur together but are actually orthogonal.

What you get back

Suspense tree: <ProfileHeader> resolves fast, renders immediately, no boundary needed if it's not the bottleneck. A Suspense boundary around <OrderHistory> (fallback: OrderHistorySkeleton) and a separate one around <InventoryStatus> (fallback: InventoryStatusSkeleton) sit as siblings, so the order history table appears well before the 2-second inventory check resolves, instead of both being gated behind the slower one.

Verified against

Claude Code Sonnet 4.6 · 2026-07-21

v0 by Vercel 2026.6 · 2026-07-22

Changelog

  • 2026-07-21 Initial version, tested against Claude Code on a Next.js 16 dashboard page with an external API dependency.

Need this built into your business?

If a prompt isn't enough — custom software, built and maintained for you — that's Scult's day job.

EXPLORE CUSTOM SOFTWARE
All Next.js prompts

Check your AI visibility

One URL in, a 0–100 score and the exact fixes out.

RUN THE CHECK

Browse all the tools

15 tools across six categories
13 of them never send your data anywhere

Free · No signup · No trial clock

SEE THE DIRECTORY