diff --git a/packages/next/src/client/components/router-reducer/fetch-server-response.ts b/packages/next/src/client/components/router-reducer/fetch-server-response.ts index 2af83aa8a203c..1b8c4d6f2787a 100644 --- a/packages/next/src/client/components/router-reducer/fetch-server-response.ts +++ b/packages/next/src/client/components/router-reducer/fetch-server-response.ts @@ -56,6 +56,7 @@ export async function fetchServerResponse( [NEXT_ROUTER_STATE_TREE]: string [NEXT_URL]?: string [NEXT_ROUTER_PREFETCH_HEADER]?: '1' + 'x-deployment-id'?: string } = { // Enable flight response [RSC_HEADER]: '1', @@ -79,6 +80,10 @@ export async function fetchServerResponse( headers[NEXT_URL] = nextUrl } + if (process.env.NEXT_DEPLOYMENT_ID) { + headers['x-deployment-id'] = process.env.NEXT_DEPLOYMENT_ID + } + const uniqueCacheQuery = hexHash( [ headers[NEXT_ROUTER_PREFETCH_HEADER] || '0', diff --git a/test/production/deployment-id-handling/app/app/from-app/page.tsx b/test/production/deployment-id-handling/app/app/from-app/page.tsx index 3fe13fd21f25b..048ad523fc0e5 100644 --- a/test/production/deployment-id-handling/app/app/from-app/page.tsx +++ b/test/production/deployment-id-handling/app/app/from-app/page.tsx @@ -1,6 +1,8 @@ 'use client' -import testImage from '../../public/test.jpg' + +import Link from 'next/link' import Image from 'next/image' +import testImage from '../../public/test.jpg' export default function Page() { return ( @@ -19,6 +21,9 @@ export default function Page() { > click me + + other app + > ) } diff --git a/test/production/deployment-id-handling/app/app/other-app/page.tsx b/test/production/deployment-id-handling/app/app/other-app/page.tsx new file mode 100644 index 0000000000000..0822e92df3c50 --- /dev/null +++ b/test/production/deployment-id-handling/app/app/other-app/page.tsx @@ -0,0 +1,24 @@ +'use client' +import testImage from '../../public/test.jpg' +import Image from 'next/image' + +export default function Page() { + return ( + <> +
{process.env.NEXT_DEPLOYMENT_ID}
+ + + > + ) +} diff --git a/test/production/deployment-id-handling/app/global.css b/test/production/deployment-id-handling/app/global.css index af9c754fa2cc5..57ad414c1827c 100644 --- a/test/production/deployment-id-handling/app/global.css +++ b/test/production/deployment-id-handling/app/global.css @@ -1,5 +1,5 @@ html { - font-size: 14rem; + font-size: 1.4rem; color: white; background: black; } diff --git a/test/production/deployment-id-handling/deployment-id-handling.test.ts b/test/production/deployment-id-handling/deployment-id-handling.test.ts index 895b0ce992d29..15f39f76ad0f2 100644 --- a/test/production/deployment-id-handling/deployment-id-handling.test.ts +++ b/test/production/deployment-id-handling/deployment-id-handling.test.ts @@ -1,5 +1,5 @@ import { nextTestSetup } from 'e2e-utils' -import { check } from 'next-test-utils' +import { check, retry } from 'next-test-utils' import { join } from 'node:path' describe.each(['NEXT_DEPLOYMENT_ID', 'CUSTOM_DEPLOYMENT_ID'])( @@ -51,7 +51,9 @@ describe.each(['NEXT_DEPLOYMENT_ID', 'CUSTOM_DEPLOYMENT_ID'])( const requests = [] browser.on('request', (req) => { - requests.push(req.url()) + if (req.url().includes('/_next/static')) { + requests.push(req.url()) + } }) await browser.elementByCss('#dynamic-import').click() @@ -81,8 +83,37 @@ describe.each(['NEXT_DEPLOYMENT_ID', 'CUSTOM_DEPLOYMENT_ID'])( }) } ) + + it('should contain deployment id in RSC payload request headers', async () => { + const rscHeaders = [] + const browser = await next.browser('/from-app', { + beforePageLoad(page) { + page.on('request', async (req) => { + const headers = await req.allHeaders() + if (headers['rsc']) { + rscHeaders.push(headers) + } + }) + }, + }) + + await browser.elementByCss('#other-app').click() + + await retry(async () => { + expect(await browser.elementByCss('h1').text()).toBe('other app') + expect(await browser.url()).toContain('/other-app') + expect(rscHeaders.length).toBeGreaterThan(0) + }) + + expect( + rscHeaders.every( + (headers) => headers['x-deployment-id'] === deploymentId + ) + ).toBe(true) + }) } ) + describe('deployment-id-handling disabled', () => { const deploymentId = Date.now() + '' const { next } = nextTestSetup({ diff --git a/test/turbopack-build-tests-manifest.json b/test/turbopack-build-tests-manifest.json index 7f374ce40e90c..0437f72f2b5c9 100644 --- a/test/turbopack-build-tests-manifest.json +++ b/test/turbopack-build-tests-manifest.json @@ -14779,10 +14779,12 @@ "deployment-id-handling enabled with CUSTOM_DEPLOYMENT_ID should append dpl query to all assets correctly for /from-app", "deployment-id-handling enabled with CUSTOM_DEPLOYMENT_ID should append dpl query to all assets correctly for /from-app/edge", "deployment-id-handling enabled with CUSTOM_DEPLOYMENT_ID should append dpl query to all assets correctly for /pages-edge", + "deployment-id-handling enabled with CUSTOM_DEPLOYMENT_ID should contain deployment id in RSC payload request headers", "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should append dpl query to all assets correctly for /", "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should append dpl query to all assets correctly for /from-app", "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should append dpl query to all assets correctly for /from-app/edge", - "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should append dpl query to all assets correctly for /pages-edge" + "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should append dpl query to all assets correctly for /pages-edge", + "deployment-id-handling enabled with NEXT_DEPLOYMENT_ID should contain deployment id in RSC payload request headers" ], "pending": [], "flakey": [],