Challenge: Keep the Shell Stable with Local RSC Simulation
Learn how to simulate the RSC mental model locally using use() and Suspense to keep a stable shell while slower regions stream in.
We'll cover the following...
Problem statement
You’re building a Support Ticket Desk UI for a larger product. The users should see a stable shell and useful structure immediately, while slower regions progressively appear as data and code become available. Use Suspense boundaries to keep retries localized, design layout-stable skeletons for fallbacks, and prefer intent-based preloading (hover/focus) for optional panels so the UI feels progressive rather than blocked.
Success criteria
The shell never disappears (header + columns remain mounted during loading/retry).
Once the ticket queue is visible, selecting a ticket must not re-suspend the queue.
Selecting a ticket shows a fast header (subject + status) that remains visible while the slow conversation thread streams in.
If the thread fails, show a recovery UI with Retry that refetches only the thread region.
Technical requirements: Implement the following features step by step:
Task 1: Cache layer (RSC-like locally)
Implement
read(key),preload(key),invalidate(key)incache.jssouse()can suspend.
Task 2: API wrappers (server seam)
Implement wrapper functions in
api.jsthat callfakeServer()with keys:getTicketQueue()→"queue"getTicketHeader(id)→header:${id}getTicketThread(id)→thread:${id}preloadTicket(id)→ preload header + thread
Task 3:
TicketQueueregion (Suspense + intent preload)Build the queue UI using
use(getTicketQueue()).Add hover/focus intent preloading:
preloadTicket(id).
Task 4:
TicketViewerregion (nested Suspense + localized retry)Fast header under Suspense (
use(getTicketHeader(id)))Slow thread under nested Suspense + ErrorBoundary
Retry invalidates only
thread:${id}