mirror of
https://github.com/hanzoai/next.js.git
synced 2026-10-30 14:46:38 +00:00
### What? Ignore router prefetch protocol headers when the request is not classified as an RSC request. Add a dedicated force-dynamic App Router fixture that verifies HTML and valid RSC prefetch behavior. ### Why? A non-RSC HTML request with `Next-Router-Prefetch: 1` could enter the partial prefetch tree path, produce a null active cache node, and suspend the HTML render until timeout. ### How? Determine `isRSCRequest` before parsing prefetch modes, then require it for prefetch modes `1`, `2`, and `3`, including route-tree prefetch classification. The regression fixture uses an abort timeout to fail quickly if the HTML response hangs and separately confirms RSC prefetches remain valid. ### Verification - `pnpm build-all` - `NEXT_TEST_PREFER_OFFLINE=1 pnpm test-start-turbo test/e2e/app-dir/non-rsc-router-prefetch/non-rsc-router-prefetch.test.ts` - `NEXT_TEST_PREFER_OFFLINE=1 pnpm test-start-webpack test/e2e/app-dir/non-rsc-router-prefetch/non-rsc-router-prefetch.test.ts` - `pnpm --filter=next types` <!-- NEXT_JS_LLM_PR -->
48 lines
1.1 KiB
TypeScript
48 lines
1.1 KiB
TypeScript
import { nextTestSetup } from 'e2e-utils'
|
|
import {
|
|
NEXT_ROUTER_PREFETCH_HEADER,
|
|
RSC_HEADER,
|
|
} from 'next/dist/client/components/app-router-headers'
|
|
|
|
describe('non-rsc-router-prefetch', () => {
|
|
const { next, skipped } = nextTestSetup({
|
|
files: __dirname,
|
|
skipDeployment: true,
|
|
})
|
|
|
|
if (skipped) {
|
|
return
|
|
}
|
|
|
|
beforeAll(async () => {
|
|
const res = await next.fetch('/')
|
|
await res.text()
|
|
})
|
|
|
|
it('ignores the router prefetch header for HTML requests', async () => {
|
|
const res = await next.fetch('/', {
|
|
headers: {
|
|
[NEXT_ROUTER_PREFETCH_HEADER]: '1',
|
|
},
|
|
signal: AbortSignal.timeout(5_000),
|
|
})
|
|
const html = await res.text()
|
|
|
|
expect(res.status).toBe(200)
|
|
expect(res.headers.get('content-type')).toContain('text/html')
|
|
expect(html).toContain('hello world')
|
|
})
|
|
|
|
it('honors the router prefetch header for RSC requests', async () => {
|
|
const res = await next.fetch('/', {
|
|
headers: {
|
|
[RSC_HEADER]: '1',
|
|
[NEXT_ROUTER_PREFETCH_HEADER]: '1',
|
|
},
|
|
})
|
|
|
|
expect(res.status).toBe(200)
|
|
expect(res.headers.get('content-type')).toContain('text/x-component')
|
|
})
|
|
})
|