Navigation, Linking and the Client Cache
Know how `<Link>` prefetches, what the client cache keeps, how the `next/navigation` hooks behave, and how `redirect`, `notFound` and `router.refresh` interact with caches and history in the Next.js 16 App Router.
Key points
- 1
<Link>prefetches in production only. By default static routes are prefetched in full, and dynamic routes down to the nearestloading.js.prefetch={true}prefetches the full route, and App Routerprefetch={false}disables viewport and hover prefetching. - 2
The client cache stores RSC payloads in memory.
staleTimes.dynamicdefaults to 0 s (since v15) andstaleTimes.staticto 5 min, which also coversprefetch={true}androuter.prefetch(). Back/forward reuses cached pages whateverstaleTimessays. - 3
router.refresh()re-renders Server Components and keeps unaffected client and browser state. It clears the client cache for the route, but not server caches: userevalidatePath,revalidateTagorupdateTagfor those. - 4
redirect()gives 307 (permanentRedirectgives 308). In a Server Action it does a client-side navigation with JS, or a 303 for a native form POST, and defaults topushhistory there (replaceelsewhere). It throws, so code after it never runs. - 5
useSearchParamson a statically prerendered page needs a<Suspense>boundary, ornext buildfails. Layouts never receivesearchParams. With Cache Components,usePathnameanduseParamssuspend for params not covered bygenerateStaticParams. - 6
useSelectedLayoutSegmentreturns the active segment one level below the calling layout (ornull).useSelectedLayoutSegmentsreturns an array that includes route groups, with catch-all matches joined into one string. - 7
With Cache Components, pages are hidden with
<Activity>(up to 3 routes), so state survives navigation. Use URL-derived state,bfcacheIdkeys, orwindow.location.hreffor logout when state must reset.
Common traps
Putting
redirect()ornotFound()insidetry/catchswallows the framework error. Call them outside thetry, or useunstable_rethrow(e).Calling
revalidatePathafterredirectdoes nothing, becauseredirectthrows. Always invalidate first.prefetch={true}on a live dynamic page makes clicks reuse a payload up to 5 minutes old (staleTimes.static).
Read the source
Test yourself on Navigation, Linking and the Client Cache
Ten questions, with the answer and explanation after each one.