Skip to content

Router Cache misses on every navigation when Link href includes search params (15.x) #90008

@Elusive7733

Description

@Elusive7733

Link to the code that reproduces this issue

https://github.com/Elusive7733/nextjs-router-cache-search-params-bug

To Reproduce

  1. Clone the repo: git clone https://github.com/Elusive7733/nextjs-router-cache-search-params-bug
  2. pnpm install && pnpm build && pnpm start
  3. Open http://localhost:3000/home?tab=overview
  4. Open DevTools Network tab, filter by "Fetch/XHR"
  5. Click "Listings" → observe RSC network request
  6. Click "Home" → observe RSC request (should have been cached from prefetch)
  7. Click "Listings" again → another RSC request (never cached)

The app has 3 fully static pages (no cookies(), headers(), or searchParams usage) linked with search params:

  <Link href="/home?tab=overview">Home</Link>
  <Link href="/listings?tab=board">Listings</Link>
  <Link href="/investors?tab=vetted">Investors</Link>

Key observation: The page you hard-reload on is always cached (seeded entry). Pages navigated to via client-side navigation are never cached, every click triggers a full RSC fetch.

Removing the search params from the href (e.g. href="/listings" instead of href="/listings?tab=board") makes caching work correctly.

Current vs. Expected behavior

Current: Every client-side navigation to a static page triggers a full RSC fetch when the <Link> href includes search params, even though:

  • The page is fully static (prerendered)
  • staleTimes.dynamic: 30 is configured
  • The response includes x-nextjs-stale-time: 4294967294 (~136 years)
  • The prefetch response returns prerendered: true

Expected: After the initial prefetch, subsequent navigations within the stale time window should be served from the Router Cache with zero network requests - the same behavior as links without search params, or links with prefetch={true}.

Root cause in prefetch-cache-utils.js:

  1. createLazyPrefetchEntry creates an AUTO prefetch with cache key /listings (search params excluded for AUTO)
  2. Prefetch response returns prerendered: true → entry's kind is upgraded to FULL, but the cache key stays /listings (not updated to /listings?tab=board)
  3. On navigation, getExistingCacheEntry looks up /listings?tab=board (with params) → cache miss
  4. Fallback finds /listings entry but marks it aliased: true → only loading boundary used → full RSC fetch

Workaround: <Link href="/listings?tab=board" prefetch={true}> - forces FULL prefetch from the start, which keys with search params immediately

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 25.2.0: Tue Nov 18 21:08:48 PST 2025; root:xnu-12377.61.12~1/RELEASE_ARM64_T8132
  Available memory (MB): 16384
  Available CPU cores: 10
Binaries:
  Node: 22.14.0
  npm: 10.9.2
  Yarn: 1.22.22
  pnpm: 10.24.0
Relevant Packages:
  next: 15.5.7 // An outdated version detected (latest is 16.1.6), upgrade is highly recommended!
  eslint-config-next: N/A
  react: 19.1.2
  react-dom: 19.1.2
  typescript: 5.9.3
Next.js Config:
  output: N/A
 ⚠ An outdated version detected (latest is 16.1.6), upgrade is highly recommended!
   Please try the latest canary version (`npm install next@canary`) to confirm the issue still exists before creating a new issue.
   Read more - https://nextjs.org/docs/messages/opening-an-issue

Which area(s) are affected? (Select all that apply)

Linking and Navigating

Which stage(s) are affected? (Select all that apply)

Vercel (Deployed), next start (local), next dev (local)

Additional context


Tested on 16.2.0-canary.45, the bug is fixed in canary due to the new segment-cache architecture with Fallback wildcard tokens. However, this affects all users on 15.x stable with no documented workaround.

Workaround for 15.x: Add prefetch={true} to <Link> components that include search params in the href.

Filing this for:

  1. Awareness - this is a common pattern (tabs, filters via search params) with no documentation about the caching pitfall
  2. Potential 15.x backport consideration
  3. Searchability — so others hitting this find the workaround

Metadata

Metadata

Assignees

No one assigned

    Labels

    Linking and NavigatingRelated to Next.js linking (e.g., <Link>) and navigation.

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions