Skip to content

Commit 7ac36d8

Browse files
authored
Revert "[next-server] skip setting vary header for basic routes (#77797)"
This reverts commit f2cf3dc.
1 parent 5136f8e commit 7ac36d8

File tree

3 files changed

+42
-5
lines changed

3 files changed

+42
-5
lines changed

packages/next/src/server/base-server.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ import {
104104
NEXT_ROUTER_SEGMENT_PREFETCH_HEADER,
105105
NEXT_DID_POSTPONE_HEADER,
106106
NEXT_URL,
107+
NEXT_ROUTER_STATE_TREE_HEADER,
107108
NEXT_IS_PRERENDER_HEADER,
108109
} from '../client/components/app-router-headers'
109110
import type {
@@ -2021,16 +2022,21 @@ export default abstract class Server<
20212022
isAppPath: boolean,
20222023
resolvedPathname: string
20232024
): void {
2025+
const baseVaryHeader = `${RSC_HEADER}, ${NEXT_ROUTER_STATE_TREE_HEADER}, ${NEXT_ROUTER_PREFETCH_HEADER}, ${NEXT_ROUTER_SEGMENT_PREFETCH_HEADER}`
2026+
const isRSCRequest = getRequestMeta(req, 'isRSCRequest') ?? false
2027+
20242028
let addedNextUrlToVary = false
20252029

20262030
if (isAppPath && this.pathCouldBeIntercepted(resolvedPathname)) {
20272031
// Interception route responses can vary based on the `Next-URL` header.
20282032
// We use the Vary header to signal this behavior to the client to properly cache the response.
2029-
res.appendHeader('vary', `${NEXT_URL}`)
2033+
res.appendHeader('vary', `${baseVaryHeader}, ${NEXT_URL}`)
20302034
addedNextUrlToVary = true
2035+
} else if (isAppPath || isRSCRequest) {
2036+
// We don't need to include `Next-URL` in the Vary header for non-interception routes since it won't affect the response.
2037+
// We also set this header for pages to avoid caching issues when navigating between pages and app.
2038+
res.appendHeader('vary', baseVaryHeader)
20312039
}
2032-
// For other cases such as App Router requests or RSC requests we don't need to set vary header since we already
2033-
// have the _rsc query with the unique hash value.
20342040

20352041
if (!addedNextUrlToVary) {
20362042
// Remove `Next-URL` from the request headers we determined it wasn't necessary to include in the Vary header.

test/e2e/app-dir/app/index.test.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,27 @@ describe('app dir - basic', () => {
323323
expect(res.headers.get('Content-Type')).toBe('text/x-component')
324324
})
325325

326+
it('should return the `vary` header from edge runtime', async () => {
327+
const res = await next.fetch('/dashboard')
328+
expect(res.headers.get('x-edge-runtime')).toBe('1')
329+
expect(res.headers.get('vary')).toBe(
330+
'RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch'
331+
)
332+
})
333+
334+
it('should return the `vary` header from pages for flight requests', async () => {
335+
const res = await next.fetch('/', {
336+
headers: {
337+
['RSC'.toString()]: '1',
338+
},
339+
})
340+
expect(res.headers.get('vary')).toBe(
341+
isNextDeploy
342+
? 'RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch'
343+
: 'RSC, Next-Router-State-Tree, Next-Router-Prefetch, Next-Router-Segment-Prefetch, Accept-Encoding'
344+
)
345+
})
346+
326347
it('should pass props from getServerSideProps in root layout', async () => {
327348
const $ = await next.render$('/dashboard')
328349
expect($('title').first().text()).toBe('hello world')

test/e2e/vary-header/test/index.test.ts

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,21 @@ describe('Vary Header Tests', () => {
1212
expect(res.headers.get('vary')).toContain('Custom-Header')
1313
})
1414

15-
it('should preserve custom vary header', async () => {
15+
it('should preserve custom vary header and append RSC headers in app route handlers', async () => {
1616
const res = await next.fetch('/normal')
1717
const varyHeader = res.headers.get('vary')
1818

1919
// Custom header is preserved
2020
expect(varyHeader).toContain('User-Agent')
2121
expect(res.headers.get('cache-control')).toBe('s-maxage=3600')
22+
23+
// Next.js internal headers are appended
24+
expect(varyHeader).toContain('RSC')
25+
expect(varyHeader).toContain('Next-Router-State-Tree')
26+
expect(varyHeader).toContain('Next-Router-Prefetch')
2227
})
2328

24-
it('should preserve middleware vary header', async () => {
29+
it('should preserve middleware vary header in combination with route handlers', async () => {
2530
const res = await next.fetch('/normal')
2631
const varyHeader = res.headers.get('vary')
2732
const customHeader = res.headers.get('my-custom-header')
@@ -32,5 +37,10 @@ describe('Vary Header Tests', () => {
3237
// Both middleware and route handler vary headers are preserved
3338
expect(varyHeader).toContain('my-custom-header')
3439
expect(varyHeader).toContain('User-Agent')
40+
41+
// Next.js internal headers are still present
42+
expect(varyHeader).toContain('RSC')
43+
expect(varyHeader).toContain('Next-Router-State-Tree')
44+
expect(varyHeader).toContain('Next-Router-Prefetch')
3545
})
3646
})

0 commit comments

Comments
 (0)