Next.js Curriculum
MediumCaching Architecture100% Free25 min read

The Client-Side Router Cache & Stale Prefetch Pitfalls

The 30-Second Interview Answer

The client-side Router Cache stores rendered React Server Component Flight payloads in browser memory during a user session. When users navigate, Next.js serves pages instantly from this client cache. However, if data changes on the server without client awareness, users see stale UI until the staleTime expires, router.refresh() is called, or a Server Action triggers automatic revalidation.

Learning Objectives

Explain how the browser-side Router Cache improves perceived navigation speed.

Diagnose stale UI bugs caused by Link prefetching and Router Cache retention.

Configure staleTimes in next.config.js to control dynamic and static retention windows.

Force client-side re-synchronization using useRouter().refresh().

Prerequisites & Background Knowledge
Client-side routingLink prefetchingBrowser memory lifecycle

Why Interviewers Care

One of the most notorious sources of production bug reports in App Router applications. Tests deep practical experience.

The Challenge

What causes the client-side Router Cache to display stale data after navigation? How do you configure prefetch behavior on <Link> and programmatically force a fresh server render?

Code Architecture & Implementation

1// app/components/Navigation.tsx
2'use client';
3
4import Link from 'next/link';
5import { useRouter } from 'next/navigation';
6import { useTransition } from 'react';
7
8export function NavigationBar() {
9 const router = useRouter();
10 const [isPending, startTransition] = useTransition();
11
12 const handleManualSync = () => {
13 startTransition(() => {
14 // router.refresh() purges the client Router Cache
15 // and re-fetches current Server Components from the server
16 router.refresh();
17 });
18 };
19
20 return (
21 <nav className="flex gap-4 p-4 border-b">
22 {/* Default: prefetch={true} prefetches full RSC payload on viewport entry */}
23 <Link href="/dashboard">Dashboard (Full Prefetch)</Link>
24
25 {/* prefetch={false}: Prefetches only shared layouts; leaves page dynamic */}
26 <Link href="/live-feed" prefetch={false}>
27 Live Feed (No Prefetch)
28 </Link>
29
30 <button onClick={handleManualSync} disabled={isPending}>
31 {isPending ? 'Syncing...' : 'Force Refresh Data'}
32 </button>
33 </nav>
34 );
35}

Architectural Explanation

When <Link> components enter the user viewport, Next.js prefetches their RSC payload and stores it in the client Router Cache. If another user mutates the backend data in the interim, clicking that link renders the prefetched (stale) payload. To fix this: 1) Server Actions should perform mutations, as they automatically invalidate the Router Cache, 2) use router.refresh() when updating via external API or third-party client state, and 3) set prefetch={false} on links pointing to rapidly changing live dashboards.

Common Mistakes & Anti-Patterns

Assuming `window.location.reload()` is required when `router.refresh()` preserves client state and scroll position while re-rendering RSCs.

Leaving `prefetch={true}` on hundreds of links on a single page, flooding the server with prefetch requests.

Thinking `revalidatePath()` in a Route Handler automatically refreshes currently open client browser tabs.

Interview Follow-Up Traps

The interviewer asks: "Does router.refresh() reset client component state (like useState)?" No! Because it streams updated RSC Flight data, React reconciles the tree and preserves existing Client Component state.

Frequently Asked Questions

Does the client Router Cache survive page reloads?

No. The client Router Cache is held purely in browser RAM and is wiped on hard page reloads.

It only prefetches when the user hovers over the link, rather than when the link enters the viewport.

The HTTP browser cache stores raw HTML/assets based on Cache-Control headers. The Router Cache stores parsed React Server Component Flight payload trees.