diff --git a/packages/next/src/build/index.ts b/packages/next/src/build/index.ts index 2f4fa5511b726..13d020d1ae26d 100644 --- a/packages/next/src/build/index.ts +++ b/packages/next/src/build/index.ts @@ -374,6 +374,8 @@ export default async function build( silent: false, }) ) + + process.env.NEXT_DEPLOYMENT_ID = config.experimental.deploymentId || '' NextBuildContext.config = config let configOutDir = 'out' diff --git a/packages/next/src/build/webpack/plugins/define-env-plugin.ts b/packages/next/src/build/webpack/plugins/define-env-plugin.ts index 0d65fe3a884bd..2cba3329788c2 100644 --- a/packages/next/src/build/webpack/plugins/define-env-plugin.ts +++ b/packages/next/src/build/webpack/plugins/define-env-plugin.ts @@ -99,7 +99,7 @@ export function getDefineEnv({ config.experimental.useDeploymentIdServerActions ), 'process.env.NEXT_DEPLOYMENT_ID': JSON.stringify( - config.experimental.deploymentId + config.experimental.deploymentId || false ), 'process.env.__NEXT_FETCH_CACHE_KEY_PREFIX': JSON.stringify(fetchCacheKeyPrefix), diff --git a/packages/next/src/export/worker.ts b/packages/next/src/export/worker.ts index cfed198f0bcbb..d0c6af804af95 100644 --- a/packages/next/src/export/worker.ts +++ b/packages/next/src/export/worker.ts @@ -64,9 +64,6 @@ async function exportPageImpl( trailingSlash, } = input - if (input.renderOpts.deploymentId) { - process.env.NEXT_DEPLOYMENT_ID = input.renderOpts.deploymentId - } if (enableExperimentalReact) { process.env.__NEXT_EXPERIMENTAL_REACT = 'true' } diff --git a/packages/next/src/server/base-server.ts b/packages/next/src/server/base-server.ts index ce1d5f92b77d2..71b16c52c5243 100644 --- a/packages/next/src/server/base-server.ts +++ b/packages/next/src/server/base-server.ts @@ -471,10 +471,8 @@ export default abstract class Server { this.nextFontManifest = this.getNextFontManifest() if (process.env.NEXT_RUNTIME !== 'edge') { - if (this.nextConfig.experimental.deploymentId) { - process.env.NEXT_DEPLOYMENT_ID = - this.nextConfig.experimental.deploymentId - } + process.env.NEXT_DEPLOYMENT_ID = + this.nextConfig.experimental.deploymentId || '' } this.renderOpts = { diff --git a/packages/next/src/server/config.ts b/packages/next/src/server/config.ts index 56a811c5d5d34..a14819bf37cd7 100644 --- a/packages/next/src/server/config.ts +++ b/packages/next/src/server/config.ts @@ -518,6 +518,11 @@ function assignDefaults( result.experimental.deploymentId = process.env.NEXT_DEPLOYMENT_ID } + // can't use this one without the other + if (result.experimental?.useDeploymentIdServerActions) { + result.experimental.useDeploymentId = true + } + // use the closest lockfile as tracing root if (!result.experimental?.outputFileTracingRoot) { let rootDir = findRootDir(dir) diff --git a/packages/next/src/server/next-server.ts b/packages/next/src/server/next-server.ts index c3c7855aff5c3..a453d2a06a10c 100644 --- a/packages/next/src/server/next-server.ts +++ b/packages/next/src/server/next-server.ts @@ -180,10 +180,8 @@ export default class NextNodeServer extends BaseServer { if (this.renderOpts.nextScriptWorkers) { process.env.__NEXT_SCRIPT_WORKERS = JSON.stringify(true) } - - if (this.nextConfig.experimental.deploymentId) { - process.env.NEXT_DEPLOYMENT_ID = this.nextConfig.experimental.deploymentId - } + process.env.NEXT_DEPLOYMENT_ID = + this.nextConfig.experimental.deploymentId || '' if (!this.minimalMode) { this.imageResponseCache = new ResponseCache(this.minimalMode) diff --git a/test/production/deployment-id-handling/app/next.config.js b/test/production/deployment-id-handling/app/next.config.js index affa3e66115e0..0beb0297db7d3 100644 --- a/test/production/deployment-id-handling/app/next.config.js +++ b/test/production/deployment-id-handling/app/next.config.js @@ -1,5 +1,5 @@ module.exports = { experimental: { - useDeploymentId: true, + useDeploymentId: !!process.env.USE_DEPLOYMENT_ID, }, } 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 6fed0614c4431..0aa43c51de068 100644 --- a/test/production/deployment-id-handling/deployment-id-handling.test.ts +++ b/test/production/deployment-id-handling/deployment-id-handling.test.ts @@ -5,11 +5,12 @@ import { join } from 'node:path' const deploymentId = Date.now() + '' createNextDescribe( - 'deployment-id-handling', + 'deployment-id-handling enabled', { files: join(__dirname, 'app'), env: { NEXT_DEPLOYMENT_ID: deploymentId, + USE_DEPLOYMENT_ID: '1', }, }, ({ next }) => { @@ -83,3 +84,83 @@ createNextDescribe( ) } ) + +createNextDescribe( + 'deployment-id-handling disabled', + { + files: join(__dirname, 'app'), + env: { + NEXT_DEPLOYMENT_ID: deploymentId, + }, + }, + ({ next }) => { + it.each([ + { urlPath: '/' }, + { urlPath: '/pages-edge' }, + { urlPath: '/from-app' }, + { urlPath: '/from-app/edge' }, + ])( + 'should not append dpl query to all assets for $urlPath', + async ({ urlPath }) => { + const $ = await next.render$(urlPath) + + expect($('#deploymentId').text()).not.toBe(deploymentId) + + const scripts = Array.from($('script')) + expect(scripts.length).toBeGreaterThan(0) + + for (const script of scripts) { + if (script.attribs.src) { + expect(script.attribs.src).not.toContain('dpl=' + deploymentId) + } + } + + const links = Array.from($('link')) + expect(links.length).toBeGreaterThan(0) + + for (const link of links) { + if (link.attribs.href) { + if (link.attribs.as === 'font') { + expect(link.attribs.href).not.toContain('dpl=' + deploymentId) + } else { + expect(link.attribs.href).not.toContain('dpl=' + deploymentId) + } + } + } + + const browser = await next.browser(urlPath) + const requests = [] + + browser.on('request', (req) => { + requests.push(req.url()) + }) + + await browser.elementByCss('#dynamic-import').click() + + await check( + () => (requests.length > 0 ? 'success' : JSON.stringify(requests)), + 'success' + ) + + try { + expect( + requests.every((item) => !item.includes('dpl=' + deploymentId)) + ).toBe(true) + } finally { + require('console').error('requests', requests) + } + } + ) + + it.each([{ pathname: '/api/hello' }, { pathname: '/api/hello-app' }])( + 'should not have deployment id env available', + async ({ pathname }) => { + const res = await next.fetch(pathname) + + expect(await res.json()).not.toEqual({ + deploymentId, + }) + } + ) + } +)