Skip to content

Fix/prefetch always 200#85643

Closed
denesbeck wants to merge 5 commits into
vercel:canaryfrom
denesbeck:fix/prefetch-always-200
Closed

Fix/prefetch always 200#85643
denesbeck wants to merge 5 commits into
vercel:canaryfrom
denesbeck:fix/prefetch-always-200

Conversation

@denesbeck
Copy link
Copy Markdown
Contributor

@denesbeck denesbeck commented Oct 31, 2025

Fixes: #85121

Starting from Next.js v15.4.1 (commit 256cd5b571), prefetch requests for SSG/ISR pages always returned 200 OK status codes instead of 304 Not Modified, even when the content hadn't changed. This forced full payload downloads on every prefetch (e.g., on hover or in-viewport), unnecessarily increasing CDN traffic and bandwidth costs.

Root Cause:
In commit 256cd5b571 ("Add response handling inside handlers"), the Pages Router handler was modified to create RenderResult instances with Buffer.from() for cached content:

The problem: RenderResult.isDynamic returns true when the response is a Buffer (not a string):

public get isDynamic(): boolean {
  return typeof this.response !== 'string'  // Buffer !== 'string' → true
}

Test repository for testing changes (to prevent version conflicts): https://github.com/denesbeck/next-test-304
Simply package the Next.js version from this branch into the repository. Then, run npm run build and npm run start.

Note: Firefox may show different behavior as it handles prefetch caching with different strategies that don't always use the same HTTP cache validation mechanisms as Chrome. However, the server-side fix is correct and working as expected - the server properly generates ETags and returns 304 responses when appropriate. The difference is in how browsers choose to send (or not send) the If-None-Match header for prefetch requests.

@ijjk
Copy link
Copy Markdown
Member

ijjk commented Nov 1, 2025

Allow CI Workflow Run

  • approve CI run for commit: c19861c

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

@denesbeck denesbeck closed this by deleting the head repository Jan 22, 2026
@github-actions github-actions Bot added the locked label Feb 6, 2026
@github-actions github-actions Bot locked as resolved and limited conversation to collaborators Feb 6, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Prefetched SSG/ISR routes always return 200 instead of 304 since v15.4.1

2 participants