Study notes · 10% of the exam

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. 1

    <Link> prefetches in production only. By default static routes are prefetched in full, and dynamic routes down to the nearest loading.js. prefetch={true} prefetches the full route, and App Router prefetch={false} disables viewport and hover prefetching.

  2. 2

    The client cache stores RSC payloads in memory. staleTimes.dynamic defaults to 0 s (since v15) and staleTimes.static to 5 min, which also covers prefetch={true} and router.prefetch(). Back/forward reuses cached pages whatever staleTimes says.

  3. 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: use revalidatePath, revalidateTag or updateTag for those.

  4. 4

    redirect() gives 307 (permanentRedirect gives 308). In a Server Action it does a client-side navigation with JS, or a 303 for a native form POST, and defaults to push history there (replace elsewhere). It throws, so code after it never runs.

  5. 5

    useSearchParams on a statically prerendered page needs a <Suspense> boundary, or next build fails. Layouts never receive searchParams. With Cache Components, usePathname and useParams suspend for params not covered by generateStaticParams.

  6. 6

    useSelectedLayoutSegment returns the active segment one level below the calling layout (or null). useSelectedLayoutSegments returns an array that includes route groups, with catch-all matches joined into one string.

  7. 7

    With Cache Components, pages are hidden with <Activity> (up to 3 routes), so state survives navigation. Use URL-derived state, bfcacheId keys, or window.location.href for logout when state must reset.

Common traps

  • Putting redirect() or notFound() inside try/catch swallows the framework error. Call them outside the try, or use unstable_rethrow(e).

  • Calling revalidatePath after redirect does nothing, because redirect throws. Always invalidate first.

  • prefetch={true} on a live dynamic page makes clicks reuse a payload up to 5 minutes old (staleTimes.static).

Test yourself on Navigation, Linking and the Client Cache

Ten questions, with the answer and explanation after each one.