mport fs from 'fs-extra'
import { nextTestSetup } from 'e2e-utils'

describe('CPU Profiling', () => {
  const { next } = nextTestSetup({
    files: path.join(__dirname, 'fixtures/basic-app'),
    skipStart: true,
  })

  describe('next build --experimental-cpu-prof', () => {
    it('should create CPU profile files with meaningful names', async () => {
      await next.build({ args: ['--experimental-cpu-prof'] })

      expect(next.cliOutput).toContain('CPU profile saved')

      const profileDir = path.join

: string) => f.endsWith('.cpuprofile'))
      expect(cpuProfiles.length).toBeGreaterThan(0)

      for (const profile of cpuProfiles) {
        expect(profile).toMatch(
          /^(build-main|build-webpack-(server|client|edge-server)|build-turbopack|build

(next.testDir, '.next-profiles')
      const profileDirExists = await fs.pathExists(profileDir)
      expect(profileDirExists).toBe(true)

      const files = await fs.readdir(profileDir)
      const cpuProfiles = files.filter((f


 { nextTestSetup } from 'e2e-utils'

describe('handle already sent response', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should work with fetch', async () => {
    expect(next.cliOutput).toContain('▲ Next.js')
    expect(next.cliOutput).toContain('- Local:')

    let res = await next.fetch('/')
    let text = await res.text()
    expect(text).toEqual('already sent')

    res = await next.fetch('/')
    text = await res.text()
    expect(text).toEqual('already sent')

    //

Props/g) || []).length >= 2) {
        break
      }
      await new Promise((resolve) => setTimeout(resolve, 1000))
    }
    if (i === 3) {
      throw new Error('Timed out waiting for logs to show')
    }

    // Headers should not be added after respon

 Check to see that there's two instances of 'getServerSideProps' in
    // the output. If there's only one, then the page was not re-rendered.
    let i
    for (i = 0; i < 3; i++) {
      if ((next.cliOutput.match(/getServerSide


from 'e2e-utils'

describe('no-op export', () => {
  describe('all server-side pages build', () => {
    const { next } = nextTestSetup({
      files: __dirname,
      skipStart: true,
    })

    it('should not error for all server-side pages build', async () => {
      await next.patchFile(
        'pages/_error.js',
        `
import React from 'react'
export default class Error extends React.Component {
  static async getInitialProps() {
    return {
      props: {
        statusCode: 'oops'
      }

{
  return {
    paths: [],
    fallback: false
  }
}
export default function Page() {
  return 'page'
}
`
      )
      const { exitCode } = await next.build()
      expect(exitCode).toBe(0)
    })
  })

  describe('empty exportPathMap', () => {
    const

}
  }
  render() {
    return 'error page'
  }
}
`
      )
      await next.patchFile(
        'pages/[slug].js',
        `
export const getStaticProps = () => {
  return {
    props: {}
  }
}
export const getStaticPaths = () =>


module.exports = {
  onDemandEntries: {
    // Make sure entries are not getting disposed.
    maxInactiveAge: 1000 * 60 * 60,
  },
  rewrites() {
    // add a rewrite so the code isn't dead-code eliminated
    return [
      {
        source: '/some-rewrite',
        destination: '/',
      },
    ]
  },
  redirects() {
    return [
      {
        source: '/redirect/me/to-about/:lang',
        destination: '/:lang/about',
        permanent: false,
      },
      {
        source: '/nonexistent',
        d

  },
      {
        source: '/shadowed-page',
        destination: '/about',
        permanent: false,
      },
      {
        source: '/redirect-query-test/:path',
        destination: '/about?foo=:path',
        permanent: false,
      },
    ]
  },
}

estination: '/about',
        permanent: false,


m 'next'
import { nextTestSetup } from 'e2e-utils'
import { version as nextVersion } from 'next/package.json'

process.env.TEST_EXPORT = '1'

describe('adapter-config export', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  it('should call onBuildComplete with correct context', async () => {
    const nonExportFiles = [
      'app/node-app/page.tsx',
      'app/node-route/route.ts',
      'app/edge-route/route.ts',
      'app/preferred-region/route.ts',
      'a

',
      'app/node-app/[slug]/page.tsx',
      'app/node-app/@dialog/default.tsx',
      'app/node-app/@dialog/[slug]/page.tsx',
    ]

    for (const file of nonExportFiles) {
      await next.remove(file)
    }

    await next.build()
    expect(next.cli

pp/isr-route/route.ts',
      'app/isr-route/[slug]/route.ts',
      'app/edge-app/page.tsx',
      'pages/api/edge-pages.ts',
      'pages/api/node-pages.ts',
      'pages/edge-pages/index.tsx',
      'pages/node-pages/index.tsx


tTestSetup } from 'e2e-utils'

describe('Invalid config syntax', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipStart: true,
      skipDeployment: true,
    })
    if (skipped) return

    it('should error when next.config.js contains syntax error', async () => {
      await next.patchFile(
        'next.config.js',
        `
      module.exports = {
        reactStrictMode: true,,
      }
    `
      )
      await next.build()

should error when next.config.mjs contains syntax error', async () => {
      // Remove any existing config files first to avoid Next.js prioritizing .js over .mjs
      await next.deleteFile('next.config.js').catch(() => {})

      await next.patchFile(

      expect(next.cliOutput).toContain(
        'Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error'
      )
      expect(next.cliOutput).toContain('SyntaxError')
    })

    it('


P build errors', () => {
  const { next, isTurbopack } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  ;(isTurbopack ? it.skip : it)(
    'should fail build from module not found',
    async () => {
      await next.patchFile(
        'pages/test.js',
        `
      __non_webpack_require__('a-cool-module')

      export function getStaticProps() {
        return {
          props: {}
        }
      }

      export default function () {
        return null
      }
    `
      )
      c

      export function getStaticProps() {
        require('fs').readFileSync('a-cool-file')
        return {
          props: {}
        }
      }

      export default function () {
        return null
      }
    `
    )
    const { cliOutput } = await ne

onst { cliOutput } = await next.build()
      expect(cliOutput).toContain('a-cool-module')
    }
  )

  it('should fail build from ENOENT in getStaticProps', async () => {
    await next.patchFile(
      'pages/test.js',
      `


import createMdx from '@next/mdx'

const withMdx = createMdx()

export default withMdx({
  typedRoutes: true,

  pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'mdx'],

  async rewrites() {
    return [
      {
        source: '/rewrite',
        destination: 'https://nextjs.org',
      },
      {
        source: '/rewrite-any/(.*)',
        destination: 'https://nextjs.org',
      },
      {
        source: '/rewrite-one-or-more/:param+',
        destination: 'https://nextjs.org',
      },
      {
        sour

 [
      {
        source: '/redirect',
        destination: 'https://nextjs.org',
        permanent: false,
      },
      {
        source: '/redirect(/v1)?/guides/:param/page',
        destination: 'https://nextjs.org',
        permanent: false,
      }

ce: '/rewrite-all/:param*',
        destination: 'https://nextjs.org',
      },
      {
        source: '/rewrite-param/:param/page',
        destination: 'https://nextjs.org',
      },
    ]
  },
  async redirects() {
    return


rt Link from 'next/link'

export function Card<T extends string>({ href }: { href: Route<T> | URL }) {
  return (
    <Link href={href}>

My Card

    </Link>
  )
}

export default function page() {
  const test = 'a/b'

  const shouldFail = (
    <>
      <Card href="/(newroot)/dashboard/another" />
      <Card href="/dashboard" />
      <Card href="/blog/a/b/c/d" />
      <Link href="/typing">test</Link>
      <Link href="/button">test</Link>
      <Link href="/buttooon">test</Link>
      <

/dashboard">test</Link>
      <Link href={`/blog/a/${test}`}>test</Link>
      <Link href="/rewrite-any">test</Link>
      <Link href="/rewrite-one-or-more">test</Link>
      <Link href="/rewrite-param/page">test</Link>
      <Link href="/rewrite-param/x/p

Link href="/blog/">test</Link>
      <Link href="/blog/a?1/b">test</Link>
      <Link href="/blog/a#1/b">test</Link>
      <Link href="/blog/v/w/z">test</Link>
      <Link href="/(newroot)/dashboard/another" />
      <Link href="


import { nextTestSetup } from 'e2e-utils'

describe('Polyfills', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    dependencies: {
      unfetch: '4.2.0',
      'isomorphic-unfetch': '3.0.0',
      'whatwg-fetch': '3.0.0',
    },
  })

  it('should alias fetch', async () => {
    const browser = await next.browser('/fetch')
    const text = await browser.elementByCss('#test-status').text()
    expect(text).toBe('pass')
  })

  it('should allow using process.env when there is an element wi

page count in output', async () => {
    const output = next.cliOutput
    expect(output).toMatch(/Generating static pages.*\(0\/5\)/g)
    expect(output).toMatch(/Generating static pages.*\(5\/5\)/g)
    expect(output.match(/Generating static pages/g).len

th `id` of `process`', async () => {
    const browser = await next.browser('/process')
    const text = await browser.elementByCss('#process').text()
    expect(text).toBe('Hello, stranger')
  })

  it('should contain generated


Setup } from 'e2e-utils'
import {
  getClientBuildManifestLoaderChunkUrlPath,
  retry,
} from 'next-test-utils'

describe('Failing to load _error', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('handles failing to load _error correctly', async () => {
    const chunk = getClientBuildManifestLoaderChunkUrlPath(
      next.testDir,
      '/_error'
    )

    const browser = await next.browser('/', {
      beforePageLoad(page) {
        page.route(`**/${chunk}*`, (route) => {

  },
    })

    await browser.eval(`window.beforeNavigate = true`)
    await browser.elementByCss('#to-broken').click()

    await retry(async () => {
      const beforeNavigate = await browser.eval('window.beforeNavigate')
      expect(beforeNavigate).to

      route.abort('blockedbyclient')
        })


tTestSetup } from 'e2e-utils'
import { check, renderViaHTTP } from 'next-test-utils'

describe('ENOENT during require', () => {
  const { next } = nextTestSetup({
    files: {
      'pages/_app.js': `
        import App from 'next/app'

        if (typeof window === 'undefined') {
          if (process.env.NEXT_PHASE !== 'phase-production-build') {
            require('fs').readdirSync('non-existent-folder')
          }
        }
        export default App
      `,
      'pages/index.js': `

export default function Page() {
          return
hello world

        }
      `,
    },
    dependencies: {},
  })

  it('should show ENOENT error correctly', async () => {
    await check(async () => {
      await renderViaHTTP(next.url, '/'

export function getStaticProps() {
          console.log('revalidate /')

          return {
            props: {
              now: Date.now()
            },
            revalidate: 1
          }
        }


g library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library.
This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library.
This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big library. This is a big li


import { nextTestSetup } from 'e2e-utils'

describe('Side-effect imports with noUncheckedSideEffectImports', () => {
  const { next, skipped } = nextTestSetup({
    files: __dirname,
    dependencies: { sass: '1.54.0' },
    skipStart: true,
  })
  if (skipped) return

  let buildResult: Awaited<ReturnType<(typeof next)['build']>>
  beforeAll(async () => {
    buildResult = await next.build()
  })

  it('Should build without typescript errors', async () => {
    // If something's wrong with our declarations

toContain('client-only')
    expect(buildResult.cliOutput).not.toContain('globals.css')
    expect(buildResult.cliOutput).not.toContain('globals.sass')
    expect(buildResult.cliOutput).not.toContain('globals.scss')
    expect(buildResult.exitCode).toBe(0)

 of these modules, TSC will error with:
    //   `Type error: Cannot find module '...' or its corresponding type declarations.`
    expect(buildResult.cliOutput).not.toContain('server-only')
    expect(buildResult.cliOutput).not.


p } from 'e2e-utils'
import { findPort, startStaticServer, stopApp } from 'next-test-utils'
import { join } from 'path'

const itHeaded = process.env.HEADLESS ? it.skip : it

describe('bfcache-routing', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  let port: number
  let app: Server

  beforeAll(async () => {
    const { exitCode } = await next.build()
    // eslint-disable-next-line jest/no-standalone-expect
    expect(exitCode).toBe(0)

    const exportDir =

stored from bfcache after an mpa navigation',
    async () => {
      // bfcache is not currently supported by CDP, so we need to run this particular test in headed mode
      // https://bugs.chromium.org/p/chromium/issues/detail?id=1317959

      const br

 join(next.testDir, 'out')
    port = await findPort()
    app = await startStaticServer(exportDir, undefined, port)
  })

  afterAll(() => {
    stopApp(app)
  })

  itHeaded(
    'should not suspend indefinitely when page is re


/ This page tests that Bun modules are properly externalized
export default function Page() {
  return
Webpack Bun Externals Test

}

export async function getServerSideProps() {
  const results = {}

  try {
    require('bun:ffi')
    results['bun:ffi'] = 'loaded'
  } catch (e) {
    results['bun:ffi'] = 'external (not found)'
  }

  try {
    require('bun:jsc')
    results['bun:jsc'] = 'loaded'
  } catch (e) {
    results['bun:jsc'] = 'external (not found)'
  }

  try {
    require('bun:sqlite')

(not found)'
  }

  try {
    require('bun:wrap')
    results['bun:wrap'] = 'loaded'
  } catch (e) {
    results['bun:wrap'] = 'external (not found)'
  }

  try {
    require('bun')
    results['bun'] = 'loaded'
  } catch (e) {
    results['bun'] = 'extern

    results['bun:sqlite'] = 'loaded'
  } catch (e) {
    results['bun:sqlite'] = 'external (not found)'
  }

  try {
    require('bun:test')
    results['bun:test'] = 'loaded'
  } catch (e) {
    results['bun:test'] = 'external


 from 'fs-extra'
import path from 'path'

function extractSourceMappingURL(jsContent) {
  // Matches both //# and //@ sourceMappingURL=...
  const match = jsContent.match(/\/\/[#@] sourceMappingURL=([^\s]+)/)
  expect(match).toBeDefined()
  return match ? match[1] : null
}

describe('Middleware source maps', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('generates a source map for Middleware', async () => {
    const middlewareManifest = await next.readJSON(
      '.next/server

.files) {
        const filePath = path.join(next.testDir, '.next', file)
        expect(await fs.pathExists(filePath)).toEqual(true)
        let sourcemap = decodeURI(
          extractSourceMappingURL(await fs.readFile(filePath, 'utf8'))
        )

/middleware-manifest.json'
    )

    for (const key in middlewareManifest.middleware) {
      const middleware = middlewareManifest.middleware[key]
      expect(middleware.files).toBeDefined()
      for (const file of middleware


', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
    dependencies: {
      firebase: 'latest',
    },
  })

  // TODO: investigate re-enabling this test in node 12 environment
  it.skip('Throws an error when building with firebase dependency with worker_threads', async () => {
    await next.patchFile(
      'next.config.js',
      `module.exports = { experimental: { workerThreads: true } }`
    )
    await next.build()
    expect(next.cliOutput).toMatch(/Build error

 /grpc_node\.node\. Module did not self-register\./
    )
  })

  it('Throws no error when building with firebase dependency without worker_threads', async () => {
    await next.build()
    expect(next.cliOutput).not.toMatch(/Build error occurred/)
    ex

occurred/)
    expect(next.cliOutput).toMatch(


 res = await next.fetch('/')
    expect(res.status).toBe(404)

    const res2 = await next.fetch('/docs/node-pages')
    expect(res2.status).toBe(200)
    expect(await res2.text()).toContain('hello world')

    expect(next.cliOutput).toContain('called modify config in adapter')
  })

  it('should call onBuildComplete with correct context', async () => {
    expect(next.cliOutput).toContain('onBuildComplete called')

    const {
      outputs,
      routing,
      config,
      ...ctx
    }: Parameters<NextA

 {
        throw new Error(
          `Invalid dir value provided for ${field} value ${ctx[field]}`
        )
      }
    }

    expect(ctx.nextVersion).toBe(nextVersion)
    expect(ctx.projectDir).toBe(next.testDir)
    expect(config?.basePath).toBe('/doc

dapter['onBuildComplete']>[0] = await next.readJSON(
      'build-complete.json'
    )

    for (const field of ['distDir', 'projectDir', 'repoRoot']) {
      expect(ctx[field]).toBeString()

      if (!fs.existsSync(ctx[field]))


ort { redirect, permanentRedirect, RedirectType } from 'next/navigation'
import type { Route } from 'next'

export default function Page() {
  function testRedirect() {
    // Invalid routes - these should cause type errors:
    redirect('/wrong-link')
    redirect('/blog/a?1/b')
    redirect(`/blog/${'a/b/c'}`)
    permanentRedirect('/nonexistent-route')
    permanentRedirect('/wrong/route')

    // Correctly typed - these should pass:
    redirect('/dashboard/another')
    redirect('/about')
    redirect(

'}`)
    permanentRedirect('/external' as Route)

    // RedirectType should be correctly typed as literal types:
    redirect('/dashboard/another', RedirectType.replace)
    redirect('/about', RedirectType.push)
    permanentRedirect('/dashboard/user', Re

'/redirect')
    redirect(`/blog/${'a/b'}`)
    redirect('https://vercel.com')
    redirect('/invalid' as Route)
    permanentRedirect('/dashboard/user')
    permanentRedirect('/blog/a/b')
    permanentRedirect(`/dashboard/${'123


State, useEffect } from 'react'
import unfetchImp from 'unfetch'
import isomorphicUnfetchImp from 'isomorphic-unfetch'

const testWhatwgFetchMethods = (whatWgFetch) => {
  return (
    whatWgFetch.Headers.name === 'Headers' &&
    whatWgFetch.Request.name === 'Request' &&
    whatWgFetch.Response.name === 'Response'
  )
}

const testFetchImports = async () => {
  const whatwgFetchImp = await import('whatwg-fetch')
  const whatwgFetchReq = require('whatwg-fetch')
  const unfetchReq = require('unfetch')
  con

chImp, isomorphicUnfetchReq].every(
      (lib) => lib.name === 'bound fetch'
    )

  return areImportsMatching &&
    testWhatwgFetchMethods(whatwgFetchReq) &&
    testWhatwgFetchMethods(whatwgFetchImp)
    ? 'pass'
    : 'fail'
}

const Page = () => {

st isomorphicUnfetchReq = require('isomorphic-unfetch')

  let areImportsMatching =
    [whatwgFetchImp.fetch, whatwgFetchReq.fetch].every(
      (lib) => lib.name === 'fetch'
    ) &&
    [unfetchImp, unfetchReq, isomorphicUnfet


ort { nextTestSetup } from 'e2e-utils'
import { join } from 'path'

describe('Top Level Error', () => {
  describe('production mode', () => {
    describe('with getInitialProps', () => {
      const { next, skipped } = nextTestSetup({
        files: join(__dirname, 'with-get-initial-props'),
        skipDeployment: true,
      })
      if (skipped) return

      it('should render error page with getInitialProps', async () => {
        const browser = await next.browser('/')
        const text = await browse

iles: join(__dirname, 'without-get-initial-props'),
        skipDeployment: true,
      })
      if (skipped) return

      it('should render error page', async () => {
        const browser = await next.browser('/')
        const text = await browser.wait

r.waitForElementByCss('#error-p').text()
        expect(text).toBe('Error Rendered with: top level error')
      })
    })

    describe('without getInitialProps', () => {
      const { next, skipped } = nextTestSetup({
        f


retry } from 'next-test-utils'

describe('allow-development-build', () => {
  describe('with NODE_ENV set to development', () => {
    const { next } = nextTestSetup({
      files: __dirname,
      env: {
        NODE_ENV: 'development',
      },
      nextConfig: {
        experimental: {
          allowDevelopmentBuild: true,
        },
      },
    })

    it('should warn about a non-standard NODE_ENV', () => {
      expect(next.cliOutput).toContain(
        'You are using a non-standard "NODE_ENV" value

nsoleLog: true,
        })

        await retry(async () => {
          const logs = await browser.log()

          const errorLogs = logs.filter((log) => log.source === 'error')

          expect(errorLogs).toEqual(
            expect.arrayContaining([

 in your environment'
      )
    })

    it.each(['app-page', 'pages-page'])(
      `should show React development errors in %s`,
      async (page) => {
        const browser = await next.browser(page, {
          pushErrorAsCo


('ci-missing-typescript-deps', () => {
  describe('missing typescript dep', () => {
    const { next } = nextTestSetup({
      files: {
        'pages/index.tsx': `
          export default function Page() {
            return
hello world

          }
        `,
      },
      env: {
        CI: '1',
      },
      skipStart: true,
      dependencies: {
        typescript: undefined,
      },
    })

    it('should show missing TypeScript dependencies error in CI', async () => {
      let error

ge(s) installed.`
      )
      expect(next.cliOutput).toContain(`Please install`)
      expect(next.cliOutput).not.toContain('Call retries were exceeded')
      expect(next.cliOutput).not.toContain('WorkerError')
    })
  })

  describe('with @types/react

await next.start().catch((err) => {
        error = err
      })

      expect(error).toBeDefined()
      expect(next.cliOutput).toContain(
        `It looks like you're trying to use TypeScript but do not have the required packa


port { nextTestSetup } from 'e2e-utils'

describe('Errors on output to public', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  it('Throws error when `distDir` is set to public', async () => {
    await next.patchFile(
      'next.config.js',
      `module.exports = { distDir: 'public' }`
    )
    await next.build()

    expect(next.cliOutput).toMatch(
      /The 'public' directory is reserved in Next\.js and can not be set as/
    )
  })

  it('Throws error wh

t next.patchFile(
      'next.config.js',
      `module.exports = { distDir: 'public', output: 'export' }`
    )
    await next.build()

    expect(next.cliOutput).toMatch(
      /The 'public' directory is reserved in Next\.js and can not be/
    )
  })
})

en export out dir is public', async () => {
    awai


. to test
// type-error reporting. Under Cache Components the build aborts up front
// with an incompatibility error before TS errors can be collected, so the
// entire suite is skipped — `describe.skip` also prevents `nextTestSetup`
// hooks from firing, so the failing build never runs.
;(process.env.__NEXT_CACHE_COMPONENTS === 'true' ? describe.skip : describe)(
  'app type checking - production mode',
  () => {
    const { next, isNextStart, isTurbopack } = nextTestSetup({
      files: __dirname,
      s

'skipped for non-start mode', () => {})
      return
    }

    let errors: string | undefined

    beforeAll(async () => {
      await next.build()
      const stderr = next.cliOutput

      errors = stderr.match(
        /===== TS errors =====(.+)===== T

kipStart: true,
      dependencies: {
        '@next/mdx': 'latest',
        '@mdx-js/loader': 'latest',
        '@mdx-js/react': 'latest',
      },
      packageJson: { type: 'module' },
    })

    if (!isNextStart) {
      it(


from 'e2e-utils'

describe('Dynamic Code Evaluation (DCE)', () => {
  const { next } = nextTestSetup({
    skipStart: true,
    dependencies: { 'function-bind': 'latest' },
    files: __dirname,
  })

  // This test is basically for https://github.com/vercel/next.js/discussions/51910
  // to make sure that some libs that we know are using `eval` but don't break
  // because it will never run into that condition, but still can't to be DCE'd.
  it('should not fail when "function-bind" package is used', async

Edge Runtime`
    )
  })
  ;(process.env.IS_TURBOPACK_TEST ? it.skip : it)(
    "should show the user's import trace",
    async () => {
      await next.patchFile(
        'middleware.js',
        `
      import { foo } from './lib/foo'
      export funct

() => {
    const { exitCode, cliOutput } = await next.build()
    expect(exitCode).toBe(0)
    expect(cliOutput).not.toContain(
      `Dynamic Code Evaluation (e. g. 'eval', 'new Function', 'WebAssembly.compile') not allowed in


 library. This is some big library. This is some big library. This is some big library. This is some big library. This is some big library.
This is some big library. This is some big library. This is some big library. This is some big library. This is some big library. This is some big library.
This is some big library. This is some big library. This is some big library. This is some big library. This is some big library. This is some big library.
This is some big library. This is some big library. This is


fetchViaHTTP } from 'next-test-utils'
import path from 'path'

const files = {
  'pages/index.js': `
    export default function Page() {
      return
hello world

    }
  `,
  'middleware.js': `
    import { NextResponse } from 'next/server'

    if (typeof EdgeRuntime === 'undefined') {
      console.log("EdgeRuntime is undefined");
    } else {
      console.log("EdgeRuntime is defined");
    }

    export default (req) => {
      return NextResponse.next({
        headers: {
          'x-runtime-v

me is addressable', () => {
  const { next } = nextTestSetup({
    files,
    dependencies: {},
  })

  test('EdgeRuntime evaluates to a string', async () => {
    const resp = await fetchViaHTTP(next.url, '/')
    expect(await resp.text()).toContain('hell

ersion': EdgeRuntime,
          'x-runtime-version-dynamic': getDynamicRuntimeVersion(self)
        }
      })
    }

    function getDynamicRuntimeVersion(from) {
      return from.EdgeRuntime;
    }
  `,
}

describe('Edge Runti


 { nextTestSetup } from 'e2e-utils'

// This isolated test installs extra dependencies (`lost`, `postcss-nested`,
// `styled-jsx-plugin-postcss`) and a custom .babelrc.js disables SWC, which
// makes the isolated install + `next build` much slower than the default 120s
// jest beforeAll timeout.
jest.setTimeout(10 * 60 * 1000)

// This test uses a custom babelrc, which Turbopack does not support.
;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)(
  'styled-jsx-plugin',
  () => {
    const { next }

d on postcss 6 and a `deasync` native addon that deadlocks
        // inside Next.js's webpack build worker on modern Node.js.
        lost: '9.0.2',
        'postcss-nested': '7.0.2',
        'styled-jsx-plugin-postcss': '4.0.1',
      },
    })

    it('

 = nextTestSetup({
      files: __dirname,
      dependencies: {
        // Use versions compatible with postcss 8. Older pinned versions
        // (`lost@8`, `postcss-nested@2`, `styled-jsx-plugin-postcss@0.1`)
        // depen


eturn data.nextDataRequests
  }

  async function resetDataRequests() {
    await fetch(`http://localhost:${proxyPort}/_test/data-requests/reset`)
  }

  async function setStall(on: boolean) {
    await fetch(
      `http://localhost:${proxyPort}/_test/stall/${on ? 'on' : 'off'}`
    )
  }

  beforeAll(async () => {
    await next.build()
    buildId = await next.readFile('.next/BUILD_ID')
    await next.start({ skipBuild: true })

    proxyChild = spawn(
      process.execPath,
      [join(next.testDir, 's

toString()
        const m = buf.match(/__PORT__:(\d+)/)
        if (m) {
          proxyChild.stdout!.off('data', onData)
          resolve(Number(m[1]))
        }
      }
      proxyChild.stdout!.on('data', onData)
      proxyChild.once('exit', (code) =>

erver.js'), next.url, '0'],
      { stdio: ['ignore', 'pipe', 'inherit'] }
    )

    proxyPort = await new Promise<number>((resolve, reject) => {
      let buf = ''
      const onData = (chunk: Buffer) => {
        buf += chunk.


tures

      <Link href="/ssg/dynamic/[slug]?slug=one" as="/ssg/fixture/mismatch">
        Dynamic Route (one level) — Prerendered
      </Link>
      : this is a Dynamic Page with a single dynamic segment that{' '}
      was returned from getStaticPaths.

      <Link href="/ssg/dynamic/[slug]?slug=two" as="/ssg/fixture/mismatch">
        Dynamic Route (one level) — Not Prerendered
      </Link>
      : this is a Dynamic Page with a single dynamic segment that{

},
        }}
        as="/ssg/fixture/mismatch"
      >
        Multi Dynamic Route (two levels) — Prerendered
      </Link>
      : this is a Dynamic Page with two dynamic segments that{' '}
      were returned from getStaticPaths<

' '}
      was not returned from getStaticPaths.

      <Link
        href={{
          pathname: '/ssg/dynamic-nested/[slug1]/[slug2]',
          query: { slug1: 'one', slug2: 'two'


from 'path'
import { FileRef, nextTestSetup } from 'e2e-utils'

// Reproduces https://github.com/vercel/next.js/issues/93336
describe('typescript paths with deprecated, inherited baseUrl', () => {
  const fixtureDir = path.join(__dirname, 'fixtures/inherited')
  const { skipped, next } = nextTestSetup({
    files: {
      '../pnpm-workspace.yaml': new FileRef(
        path.join(fixtureDir, 'pnpm-workspace.yaml')
      ),
      '../tsconfig.base.json': new FileRef(
        path.join(fixtureDir, 'tsconfig.bas

(fixtureDir, 'web/tsconfig.json')),
      app: new FileRef(path.join(fixtureDir, 'web/app')),
    },
    subDir: 'web',
    dependencies: {
      // Specifically testing compilerOptions that were deprecated in 6.0.
      // This test would fail in 7.0

e.json')
      ),
      '../packages': new FileRef(path.join(fixtureDir, 'packages')),
      'next.config.js': new FileRef(
        path.join(fixtureDir, 'web/next.config.js')
      ),
      'tsconfig.json': new FileRef(path.join


ort { Writable } from 'stream'
import path from 'path'
import crypto from 'crypto'
import { Buffer } from 'buffer'
import vm from 'vm'
import { useEffect, useState } from 'react'

export default function NodeBrowserPolyfillPage() {
  const [state, setState] = useState({})
  useEffect(() => {
    let closedStream = false

    const writable = new Writable({
      write(_chunk, _encoding, callback) {
        callback()
      },
    })

    writable.on('finish', () => {
      closedStream = true
    })

    wr

runInNewContext('a + 5', { a: 100 }),
      stream: closedStream,
    })
  }, [])

  useEffect(() => {
    if (state.vm) {
      window.didRender = true
    }
  }, [state])

  return (
    <>
      <div
        id="node-browser-polyfills"
        dangerous

itable.end()

    setState({
      path: path.join('/hello/world', 'test.txt'),
      hash: crypto.createHash('sha256').update('hello world').digest('hex'),
      buffer: Buffer.from('hello world').toString('utf8'),
      vm: vm.


rCondition(`!!window.next.router.isReady`)
    await browser.forward()
    await browser.waitForElementByCss('.about-page')
  })

  if (process.env.BROWSER_NAME !== 'safari') {
    it.each([
      { hash: '#hello?' },
      { hash: '#?' },
      { hash: '##' },
      { hash: '##?' },
      { hash: '##hello?' },
      { hash: '##hello' },
      { hash: '#hello?world' },
      { search: '?hello=world', hash: '#a', query: { hello: 'world' } },
      { search: '?hello', hash: '#a', query: { hello: '' } },

er(`/${search || ''}${hash || ''}`)

        await check(
          () =>
            browser.eval('window.next.router.isReady ? "ready" : "not ready"'),
          'ready'
        )
        expect(await browser.eval('window.location.pathname')).toBe('/')

 { search: '?hello=', hash: '#a', query: { hello: '' } },
    ])(
      'should handle query/hash correctly during query updating $hash $search',
      async ({ hash, search, query }) => {
        const browser = await next.brows


ring every 500ms
async function checkInjected(browser) {
  const start = Date.now()
  while (Date.now() - start < 5000) {
    const bodyText = await getBrowserBodyText(browser)
    if (/INJECTED/.test(bodyText)) {
      throw new Error('Vulnerable to XSS attacks')
    }
    await waitFor(500)
  }
}

export default (next: NextInstance) => {
  describe('With Security Related Issues', () => {
    it.skip('should handle invalid URL properly', async () => {
      async function invalidRequest() {
        return

             resolve(response.statusCode)
            }
          )
          request.on('error', (err) => reject(err))
          request.end()
        })
      }
      try {
        expect(await invalidRequest()).toBe(400)
        expect(await invalidRequ

new Promise((resolve, reject) => {
          const request = http.request(
            {
              hostname: `localhost`,
              port: next.appPort,
              path: `*`,
            },
            (response) => {


tSetup } from 'e2e-utils'
import { findAllTelemetryEvents } from 'next-test-utils'
import { join } from 'path'

const mockedGoogleFontResponses = require.resolve(
  './google-font-mocked-responses.js'
)

// Turbopack intentionally does not support these events
;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)(
  'next/font used telemetry',
  () => {
    const { next } = nextTestSetup({
      files: {
        pages: new FileRef(join(__dirname, 'telemetry/pages')),
      },
      env: {
        NEXT

tryEvents(
        next.cliOutput,
        'NEXT_BUILD_FEATURE_USAGE'
      )
      expect(events).toContainEqual({
        featureName: 'next/font/google',
        invocationCount: 1,
      })
      expect(events).toContainEqual({
        featureName: 'ne

_FONT_GOOGLE_MOCKED_RESPONSES: mockedGoogleFontResponses,
        NEXT_TELEMETRY_DEBUG: '1',
      },
    })

    it('should send next/font/google and next/font/local usage event', async () => {
      const events = findAllTeleme


TOM_DEPLOYMENT_ID', ''],
  ['NEXT_DEPLOYMENT_ID', ' and runtimeServerDeploymentId'],
  ['NEXT_DEPLOYMENT_ID_IMMUTABLE', ''],
])(
  'deployment-id-handling enabled with %s%s',
  (envKey, runtimeServerDeploymentId) => {
    if (
      envKey === 'NEXT_DEPLOYMENT_ID_IMMUTABLE' &&
      !process.env.IS_TURBOPACK_TEST
    ) {
      it.skip('skip for webpack', () => {})
      return
    }

    const deploymentId = Date.now() + ''
    const immutableAssetToken =
      envKey === 'NEXT_DEPLOYMENT_ID_IMMUTABLE' ? ''

ndefined,
      },
      disableAutoSkewProtection: true,
    })

    const validateTokenForRequest = (url: string) => {
      const token = url.includes('/_next/static/immutable/')
        ? // Turbopack-emitted chunks
          immutableAssetToken

 : deploymentId

    const { next } = nextTestSetup({
      files: join(__dirname, 'app'),
      env: {
        [envKey]: deploymentId,
        RUNTIME_SERVER_DEPLOYMENT_ID: runtimeServerDeploymentId
          ? '1'
          : u


statSync } from 'fs'
import { join } from 'path'

// TODO: Implement experimental.fallbackNodePolyfills
;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)(
  'Disable fallback polyfills',
  () => {
    async function getIndexPageSize() {
      // Read build manifest to get chunk files for the index page
      // this only works reliably for pages router and simple examples.
      const buildManifest = await next.readJSON('.next/build-manifest.json')

      // Get chunks for the '/' page
      const

stDir, '.next', chunkPath)
        try {
          const stats = statSync(fullChunkPath)
          totalSize += stats.size
        } catch (error) {
          console.warn(`Could not read chunk: ${chunkPath}`, error.message)
        }
      }

      // Con

 indexPageChunks = buildManifest.pages['/'] || []

      // Calculate total size of all chunks for the index page
      let totalSize = 0
      for (const chunkPath of indexPageChunks) {
        const fullChunkPath = join(next.te


tTurbopack } from 'e2e-utils'

describe('route-bundle-stats', () => {
  const { next, isNextDeploy } = nextTestSetup({
    files: __dirname,
  })

  if (isNextDeploy) {
    it('should skip', () => {})
    return
  }

  const STATS_PATH = '.next/diagnostics/route-bundle-stats.json'

  itTurbopack(
    'writes .next/diagnostics/route-bundle-stats.json after build',
    async () => {
      const raw = await next.readFile(STATS_PATH)
      const stats = JSON.parse(raw)

      expect(Array.isArray(stats)).toBe(t

JsBytes).toBe('number')
        expect(entry.firstLoadUncompressedJsBytes).toBeGreaterThan(0)
        expect(Array.isArray(entry.firstLoadChunkPaths)).toBe(true)
        expect(entry.firstLoadChunkPaths.length).toBeGreaterThan(0)

        for (const chunkP

rue)
      expect(stats.length).toBeGreaterThan(0)

      for (const entry of stats) {
        expect(typeof entry.route).toBe('string')
        expect(entry.route).toMatch(/^\//)
        expect(typeof entry.firstLoadUncompressed


utils'

describe('Promise in next config', () => {
  ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)(
    'production mode',
    () => {
      const { next, isNextStart } = nextTestSetup({
        files: __dirname,
        skipStart: true,
      })

      if (!isNextStart) {
        it('skipped for non-start mode', () => {})
        return
      }

      it('should warn when a promise is returned on webpack', async () => {
        await next.patchFile(
          'next.config.js',
          `

       return {
            webpack: async (config) => {
              return config
            }
          }
        }
      `
        )

        await next.build()
        expect(next.cliOutput).toMatch(
          /> Promise returned in next config\. ht

module.exports = (phase, { isServer }) => {


t path from 'path'
import { nextTestSetup } from 'e2e-utils'

describe('build trace with extra entries in monorepo', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipStart: true,
      skipDeployment: true,
    })
    if (skipped) return

    it('should build and trace correctly', async () => {
      const appDir = path.join(next.testDir, 'app')
      const { exitCode } = await next.runCommand(['build'], {
        cwd: appDir,

ect(exitCode).toBe(0)

      const appDirRoute1Trace = JSON.parse(
        await next.readFile('app/.next/server/app/route1/route.js.nft.json')
      )

      expect(appDirRoute1Trace.files).toContain(
        '../../../../../other/included.txt'
      )


tTestSetup } from 'e2e-utils'

describe('static-404', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  it('should export 404 page without custom _error', async () => {
    await next.build()
    await next.start()
    const html = await next.render('/non-existent')
    await next.stop()
    expect(html).toContain('This page could not be found')
  })

  it('should not export 404 page with custom _error GIP', async () => {
    await next.patchFile(
      'pages/_er

              throw new Error('exported 404 unexpectedly!!!')
            }
            return {
              statusCode,
            }
          }
        }
      `
    )
    await next.build()
    await next.deleteFile('pages/_error.js')
  })

  it('sh

ror.js',
      `
        import Error from 'next/error'
        export default class MyError extends Error {
          static getInitialProps({ statusCode, req }) {
            if (req.url === '/404' || req.url === '/404.html') {


     beforeAll(async () => {
        await next.build()
        await next.deleteFile('pages')

        requiredFilesManifest = await next.readJSON(
          join('.next/required-server-files.json')
        )

        let files = await fs.readdir(join(next.testDir, '.next'))

        for (const file of files) {
          if (
            file === 'server' ||
            file === 'required-server-files.json' ||
            file === 'node_modules' ||
            requiredFilesManifest.files.includes(join('.ne

        let nextApp = nextServer({
          conf: {},
          dir: next.testDir,
          quiet: false,
          minimalMode: true,
        })
        // @ts-expect-error
        server = await startApp(nextApp)
        // @ts-expect-error
        ap

xt', file))
          ) {
            continue
          }
          console.log('removing', join('.next', file))
          await next.deleteFile(join('.next', file))
        }

        process.env.NEXT_PRIVATE_TEST_HEADERS = '1'


t * as React from 'react'
import type { Route } from 'next'
import Form from 'next/form'

export default function Page() {
  const invalidRoutes = (
    <>
      <Form action="/wrong-link"></Form>
      <Form action="/blog/a?1/b"></Form>
      <Form action={`/blog/${'a/b/c'}`}></Form>
    </>
  )

  const validRoutes = (
    <>
      <Form action="/dashboard/another"></Form>
      <Form action="/about"></Form>
      <Form action="/redirect"></Form>
      <Form action={`/blog/${'a/b'}`}></Form>
      <Form a

id' as Route}></Form>
      <Form
        action={async (formData) => {
          'use server'
          console.log('function action', formData.get('myInput'))
        }}
      ></Form>
    </>
  )

  return (
    <>
      {invalidRoutes}
      {validRout


(

SSG Data Prefetch Fixtures

      <Link href="/ssg/basic">Non-dynamic route</Link>: this is a normal Next.js
      page that does not use dynamic routing.

      <Link href="/ssg/dynamic/[slug]" as="/ssg/dynamic/one">
        Dynamic Route (one level) — Prerendered
      </Link>
      : this is a Dynamic Page with a single dynamic segment that{' '}
      was returned from getStaticPaths.

      <Link href="/ssg/dynamic/[slug]"

ode>.
    </p>
    <p>
      <Link
        href="/ssg/dynamic-nested/[slug1]/[slug2]"
        as="/ssg/dynamic-nested/one/two"
      >
        Multi Dynamic Route (two levels) — Prerendered
      </Link>
      : this is a Dynamic Page with two dynamic segm

as="/ssg/dynamic/two">
        Dynamic Route (one level) — Not Prerendered
      </Link>
      : this is a Dynamic Page with a single dynamic segment that{' '}
      was not returned from getStaticPaths</c


 { Component } from 'react'
import Router from 'next/router'

let counter = 0

export default class extends Component {
  increase() {
    counter++
    this.forceUpdate()
  }

  visitQueryStringPage() {
    const href = { pathname: '/nav/querystring', query: { id: 10 } }
    const as = { pathname: '/nav/querystring/10', hash: '10' }
    Router.push(href, as)
  }

  render() {
    return (
      <div id="counter-page">
        <Link href="/no-such-page" id="no-such-page">
          No Such Page
        </Li

" prefetch id="no-such-page-prefetch">
          No Such Page (with prefetch)
        </Link>

This is the home.

Counter: {counter}

        <button id="increase" onClick={() => this.increase()}>
          Incre

nk>
        <br />
        <Link href="/no-such-page


sFromBuildManifest } from 'next-test-utils'
import { NextInstance } from 'e2e-utils'
import path from 'node:path'
import fs from 'fs-extra'

export default (next: NextInstance) => {
  describe('process.env', () => {
    it('should set process.env.NODE_ENV in production', async () => {
      const browser = await next.browser('/process-env')
      const nodeEnv = await browser.elementByCss('#node-env').text()
      expect(nodeEnv).toBe('production')
      await browser.close()
    })
  })

  describe('proces

ect(allClientCodeForPage).toMatch(
        /__THIS_SHOULD_ONLY_BE_DEFINED_IN_BROWSER_CONTEXT__/
      )
      expect(allClientCodeForPage).not.toMatch(
        /__THIS_SHOULD_ONLY_BE_DEFINED_IN_SERVER_CONTEXT__/
      )
    })

    it('should eliminate cli

s.browser', () => {
    it('should eliminate server only code on the client', async () => {
      const allClientCodeForPage = getContentOfPageFilesFromBuildManifest(
        next.testDir,
        '/process-env'
      )
      exp


from 'e2e-utils'
import { retry } from 'next-test-utils'
import { join } from 'node:path'

describe('deployment-id-handling disabled', () => {
  const deploymentId = Date.now() + ''
  const { next } = nextTestSetup({
    files: join(__dirname, 'app'),
    env: {
      COOKIE_SKEW: '1',
      NEXT_DEPLOYMENT_ID: 'thankyounext',
    },
    disableAutoSkewProtection: true,
  })

  it('should set set-cookie header correctly', async () => {
    const res = await next.fetch('/')
    expect(res.headers.get('set-co

nd 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).t

okie')).toBe(
      '__vdpl=thankyounext; Path=/; HttpOnly'
    )
  })

  it.each([
    { urlPath: '/' },
    { urlPath: '/pages-edge' },
    { urlPath: '/from-app' },
    { urlPath: '/from-app/edge' },
  ])(
    'should not appe


 nextTestSetup } from 'e2e-utils'
import { join } from 'path'

describe('app-dir-hide-suppressed-error-during-next-export', () => {
  const { next } = nextTestSetup({
    skipStart: true,
    files: {
      'next.config.js': new FileRef(join(__dirname, 'next.config.js')),
      app: new FileRef(join(__dirname, 'app')),
    },
  })

  it('should not log suppressed error when exporting static page', async () => {
    await expect(next.start()).rejects.toThrow('next build failed')
    expect(next.cliOutput).to

Output).toInclude('occurred prerendering page "/"')
    expect(next.cliOutput).toInclude('Export encountered errors on 1 path')
    expect(next.cliOutput).not.toInclude(
      'The specific message is omitted in production builds to avoid leaking sensitive

Include('Page build time error')
    expect(next.cli


tSetup } from 'e2e-utils'
import { join } from 'path'

describe('fallback export error', () => {
  const { next } = nextTestSetup({
    files: {
      pages: new FileRef(join(__dirname, 'pages')),
    },
    nextConfig: {
      output: 'export',
    },
    skipStart: true,
  })

  it('should have built', async () => {
    const result = await next.build()
    expect(result.exitCode).toBe(0)
  })

  it('should not error with default exportPathMap', async () => {
    const result = await next.build()
    cons

  await next.patchFile(
      'next.config.js',
      `
      module.exports = {
        output: 'export',
        exportPathMap() {
          return {
            '/': { page: '/' },
          }
        }
      }
    `
    )

    try {
      const result

ole.log(result.cliOutput)

    expect(result.exitCode).toBe(0)
    expect(result.cliOutput).not.toContain(
      'Found pages with `fallback` enabled'
    )
  })

  it('should not error with valid exportPathMap', async () => {


tSetup } from 'e2e-utils'
import { check, renderViaHTTP, waitFor } from 'next-test-utils'
import { join } from 'path'

describe('fatal-render-error', () => {
  const { next } = nextTestSetup({
    files: new FileRef(join(__dirname, 'app')),
    dependencies: {},
  })

  it('should render page without error correctly', async () => {
    const html = await renderViaHTTP(next.url, '/')
    expect(html).toContain('index page')
    expect(html).toContain('from _app')
  })

  it('should handle fatal error in _app

ser.eval('window.renderAttempts')).toBeLessThan(10)

    const html = await browser.eval('document.documentElement.innerHTML')
    expect(html).not.toContain('from _app')
    expect(html).toContain(
      'Application error: a client-side exception has occ

 and _error without loop on direct visit', async () => {
    const browser = await next.browser('/with-error')

    // wait a bit to see if we are rendering multiple times unexpectedly
    await waitFor(500)
    expect(await brow


rom 'next/dist/compiled/gzip-size'

describe('bundle-size', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  // TODO bring these numbers down for Turbopack, especially the softnav one
  // TODO these numbers simply change too often right now
  const BASE_SIZES = {
    pages: undefined, // process.env.IS_TURBOPACK_TEST ? 111_000 : 101_000,
    app: undefined, // process.env.IS_TURBOPACK_TEST ? 119_000 : 106_000,
    appClient: undefined, // process.env.IS_TURBOPACK_TEST ? 123_000 : 11

.env.IS_TURBOPACK_TEST ? 12_000 : 500,
    },
    {
      title: 'App Router: between RSC-only identical pages',
      from: '/app/a',
      to: '/app/b',
      fromInitialJs: BASE_SIZES.app,
      toInitialJs: BASE_SIZES.app,
      softNavJs: process.env.

0_000,
  }
  it.each([
    {
      title: 'Pages Router: between identical pages',
      from: '/pages/a',
      to: '/pages/b',
      fromInitialJs: BASE_SIZES.pages,
      toInitialJs: BASE_SIZES.pages,
      softNavJs: process


d by preload-viewport.test.ts. The script lives inside
// the isolated test directory so `http-proxy` can be installed via the
// `dependencies` option of `nextTestSetup`. The test process communicates with
// this server via the `_test/data-requests` and `_test/stall` endpoints.
const http = require('http')
const httpProxy = require('http-proxy')

const target = process.argv[2]
const port = Number(process.argv[3] || 0)

if (!target) {
  console.error('usage: node server.js <target> [port]')
  process.exit(

ntent-type', 'application/json')
    res.end(JSON.stringify({ nextDataRequests }))
    return
  }
  if (req.url === '/_test/data-requests/reset') {
    nextDataRequests.length = 0
    res.end('ok')
    return
  }
  if (req.url === '/_test/stall/on') {

1)
}

let stallJs = false
const nextDataRequests = []
const proxy = httpProxy.createProxyServer({ target })

const server = http.createServer(async (req, res) => {
  if (req.url === '/_test/data-requests') {
    res.setHeader('co


als with esmExternals: 'loose'", () => {
  ;(process.env.IS_TURBOPACK_TEST ? describe.skip : describe)(
    'production mode',
    () => {
      const { next, isNextStart } = nextTestSetup({
        files: __dirname,
      })

      if (!isNextStart) {
        it('skipped for non-start mode', () => {})
        return
      }

      const expected =
        /Hello <!-- -->World<!-- -->\+<!-- -->World<!-- -->\+<!-- -->World/

      it('should render the static page', async () => {
        const html = await n

xpected)
      })

      it('should render the ssr page', async () => {
        const html = await next.render('/ssr')
        expect(html).toMatch(expected)
      })

      it('should render the ssg page', async () => {
        const html = await next.ren

ext.render('/static')
        expect(html).toMatch(e


eerio from 'cheerio'

describe('Export with next/legacy/image component', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  afterEach(async () => {
    await next.patchFile(
      'next.config.js',
      '// prettier-ignore\nmodule.exports = { /* replaceme */ }\n'
    )
    await next.patchFile(
      'pages/index.js',
      `import Image from 'next/legacy/image'

const loader = undefined

export default () => (

Should succeed during export

lace(
        '{ /* replaceme */ }',
        JSON.stringify({
          output: 'export',
          images: {
            loader: 'cloudinary',
            path: 'https://example.com/',
          },
        })
      )
    )
    const { exitCode } = await n

<Image alt="icon" src="/i.png" width="10" height="10" loader={loader} />
  </div>
)
`
    )
  })

  it('should build with cloudinary loader', async () => {
    await next.patchFile('next.config.js', (content) =>
      content.rep


ig#exportTrailingSlash set to false', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  beforeAll(async () => {
    await next.build()
  })

  it('should export pages as [filename].html instead of [filename]/index.html', async () => {
    expect(await next.hasFile('out/index.html')).toBe(true)
    expect(await next.hasFile('out/about.html')).toBe(true)
    expect(await next.hasFile('out/posts.html')).toBe(true)
    expect(await next.hasFile('out/posts/single.html'

'out/index.html')
    const $ = cheerio.load(html)
    expect($('p').text()).toBe('I am a home page')

    const htmlSingle = await next.readFile('out/posts/single.html')
    const $single = cheerio.load(htmlSingle)
    expect($single('p').text()).toBe('I

)).toBe(true)

    const html = await next.readFile(


lt (next: NextInstance, render) => {
  async function get$(path: string, query?: any) {
    const html = await render(path, query)
    return cheerio.load(html)
  }
  describe('Dynamic import', () => {
    describe('default behavior', () => {
      it('should render dynamic import components', async () => {
        const $ = await get$('/dynamic/ssr')
        expect($('body').text()).toMatch(/Hello World 1/)
      })

      it('should render one dynamically imported component and load its css files', async

r css files', async () => {
        const $ = await get$('/dynamic/many-dynamic-css')
        const cssFiles = $('link[rel=stylesheet]')
        expect(cssFiles.length).toBe(3)
      })

      it('should bundle two css modules for one dynamically imported

() => {
        const $ = await get$('/dynamic/css')
        const cssFiles = $('link[rel=stylesheet]')
        expect(cssFiles.length).toBe(1)
      })

      it('should render three dynamically imported components and load thei


from 'e2e-utils'
import { check, renderViaHTTP } from 'next-test-utils'

describe('custom-error-500', () => {
  const { next } = nextTestSetup({
    files: {
      'pages/index.js': `
        export function getServerSideProps() {
          throw new Error('custom error')
        }

        export default function Page() {
          return
index page

        }
      `,
      'pages/500.js': `
        export default function Custom500() {
          return (
            <>

page

        Error.getInitialProps = ({ err }) => {
          console.log(\`called Error.getInitialProps \${!!err}\`)
          return {
            hasError: !!err
          }
        }

        export default Error
      `,
    },
    dependencies

s/500

            </>
          )
        }
      `,
      'pages/_error.js': `
        function Error({ hasError }) {
          return (
            <>

/_error

            </>
          )
        }


ort path from 'path'
import { nextTestSetup } from 'e2e-utils'

describe('build with proxy trace', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: path.join(__dirname, 'app'),
      skipStart: true,
      skipDeployment: true,
    })
    if (skipped) return

    it('should build and output trace correctly', async () => {
      const { exitCode } = await next.build({
        env: {
          TURBOREPO_TRACE_FILE: '.turbo/turborepo-trace.json',

puts).toStrictEqual(['dist/**', '!dist/cache/**'])
      expect(accessTrace.accessed.envVarKeys).toBeArray()
      expect(accessTrace.accessed.envVarKeys).toContain(
        'SSG_ROUTE_ENV_VAR_HEADER_TEXT'
      )
      expect(accessTrace.accessed.network)

  SSG_ROUTE_ENV_VAR_HEADER_TEXT: 'Welcome',
        },
      })
      expect(exitCode).toBe(0)

      const accessTrace = JSON.parse(
        await next.readFile('.turbo/turborepo-trace.json')
      )
      expect(accessTrace.out


m from 'resolve-from'
import { nextTestSetup } from 'e2e-utils'

type File = {
  filename: string
  content: string
}

const appDirFiles: File[] = [
  {
    filename: 'app/page.js',
    content: `
    export default function Page() {
      return
hello world

    }
  `,
  },
  {
    filename: 'app/layout.js',
    content: `
    export default function Layout({ children }) {
      return (

          {children}

      )
    }
  `,
  },
]
cons

 next } = nextTestSetup({
    skipStart: true,
    files: {},
    dependencies: {
      'node-pty': '0.10.1',
    },
    packageJson: {
      pnpm: {
        onlyBuiltDependencies: ['node-pty'],
      },
    },
  })

  beforeEach(async () => {
    await fs

t pagesFiles: File[] = [
  {
    filename: 'pages/another.js',
    content: `
    export default function Page() {
      return (

another page

      )
    }
  `,
  },
]

describe('build-spinners', () => {
  const {


Setup } from 'e2e-utils'

describe('config validation - warnings only', () => {
  const { next } = nextTestSetup({
    skipStart: true,
    files: __dirname,
  })

  it('should show warnings but not block the build', async () => {
    const { exitCode, cliOutput } = await next.build()

    // Build should succeed
    expect(exitCode).toBe(0)

    // Should show warnings
    expect(cliOutput).toContain('Invalid next.config.js options detected')
    expect(cliOutput).toContain(
      "Unrecognized key(s) in o

ption'"
    )
    expect(cliOutput).toContain('at "experimental"')

    // Should NOT show fatal error message
    expect(cliOutput).not.toContain('Fatal next config errors')

    // Build should complete successfully
    expect(cliOutput).toContain('Compi


        "next-env.d.ts",
             "**/*.mts",
             "**/*.ts",
             "**/*.tsx"
           ],
           "exclude": [
             "node_modules"
           ]
         }
         "
        `)
    } else {
      expect(await next.readFile('tsconfig.json')).toMatchInlineSnapshot(`
         "{
           "compilerOptions": {
             "target": "ES2017",
             "lib": [
               "dom",
               "dom.iterable",
               "esnext"
             ],
             "allowJs"

solution": "bundler",
             "resolveJsonModule": true,
             "isolatedModules": true,
             "jsx": "react-jsx",
             "plugins": [
               {
                 "name": "next"
               }
             ],
             "s

: true,
             "skipLibCheck": true,
             "strict": false,
             "noEmit": true,
             "incremental": true,
             "module": "esnext",
             "esModuleInterop": true,
             "moduleRe


from 'e2e-utils'
import { retry } from 'next-test-utils'

describe('error-hydration', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  it('should not log server-side errors', async () => {
    const browser = await next.browser('/with-error')
    const messages = await browser.log()

    expect(messages).not.toEqual(
      expect.arrayContaining([
        {
          message: expect.stringContaining('Error: custom error'),
          source: 'error',
        },
      ])
    )
  })

as any).__ERROR_PAGE_GET_INITIAL_PROPS_INVOKED_CLIENT_SIDE__
      )
    ).toBe(undefined)
  })

  it('should log a message for client-side errors, including the full, custom error', async () => {
    const browser = await next.browser('/no-error')
    awa

it('should not invoke the error page getInitialProps client-side for server-side errors', async () => {
    const browser = await next.browser('/with-error')

    expect(
      await browser.eval(
        () =>
          (window


tries', () => {
  describe('production mode', () => {
    const { next, isNextStart, isTurbopack } = nextTestSetup({
      files: path.join(__dirname, 'app'),
      skipStart: true,
    })

    if (!isNextStart || isTurbopack) {
      it('skipped for non-start or turbopack mode', () => {})
      return
    }

    it('should build and trace correctly', async () => {
      const { exitCode } = await next.build()
      expect(exitCode).toBe(0)

      const appTrace = JSON.parse(
        await next.readFile('.n

t/server/pages/another.js.nft.json')
      )
      const imageTrace = JSON.parse(
        await next.readFile('.next/server/pages/image-import.js.nft.json')
      )
      const appDirRoute1Trace = JSON.parse(
        await next.readFile('.next/server/app/r

ext/server/pages/_app.js.nft.json')
      )
      const indexTrace = JSON.parse(
        await next.readFile('.next/server/pages/index.js.nft.json')
      )
      const anotherTrace = JSON.parse(
        await next.readFile('.nex


 Output', () => {
  describe('Default Export', () => {
    const { next } = nextTestSetup({
      files: path.join(__dirname, 'fixtures/default-export'),
      skipStart: true,
    })

    it('should build and have expected export outputs', async () => {
      await next.build()

      expect(JSON.parse(await next.readFile('.next/export-marker.json')))
        .toMatchInlineSnapshot(`
        {
          "exportTrailingSlash": false,
          "hasExportPathMap": false,
          "isNextImageImported": fals

toMatchInlineSnapshot(`
        {
          "outDirectory": "out",
          "success": true,
          "version": 1,
        }
      `)
    })
  })

  describe('Custom Export', () => {
    const { next } = nextTestSetup({
      files: path.join(__dirname,

e,
          "version": 1,
        }
      `)

      const detail = JSON.parse(await next.readFile('.next/export-detail.json'))
      expect({
        ...detail,
        outDirectory: path.basename(detail.outDirectory),
      }).


mport { FileRef, nextTestSetup, type Playwright } from 'e2e-utils'
import { join } from 'path'
import { check } from 'next-test-utils'

describe('app-dir-prefetch-non-iso-url', () => {
  const { next } = nextTestSetup({
    files: {
      'next.config.js': new FileRef(join(__dirname, 'next.config.js')),
      app: new FileRef(join(__dirname, 'app')),
    },
  })

  it('should go to iso url', async () => {
    let browser: Playwright

    try {
      browser = await next.browser('/')
      await browser.elem

 => {
    let browser: Playwright

    try {
      browser = await next.browser('/')
      await browser.elementByCss('#to-non-iso').click()
      await check(() => browser.elementByCss('#page').text(), '/[slug]')
    } finally {
      if (browser) {

entByCss('#to-iso').click()
      await check(() => browser.elementByCss('#page').text(), '/[slug]')
    } finally {
      if (browser) {
        await browser.close()
      }
    }
  })

  it('should go to non-iso url', async ()


from 'e2e-utils'
import { join } from 'path'

describe('distDir package.json commonjs boundary', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    // Use "type": "module" in the project package.json so the boundary file
    // is what determines whether `.next/server/**/*.js` is loaded as CJS.
    packageJson: {
      type: 'module',
    },
  })

  it('writes the distDir package.json with the commonjs boundary', async () => {
    const distPackageJson = JSON.parse(
      await next.readFi

eadFile('.next/required-server-files.json')
    )
    // Adapters consume `requiredServerFiles.files` to seed the per-page
    // shared assets. The boundary marker must be in this list because
    // per-page nft traces do not include it.
    expect(manif

le('.next/package.json')
    )
    expect(distPackageJson).toEqual({ type: 'commonjs' })
  })

  it('lists the distDir package.json in required-server-files.json', async () => {
    const manifest = JSON.parse(
      await next.r


/ intervals/open connections shouldn't block build from exiting
setInterval(() => {}, 250)

module.exports = {
  onDemandEntries: {
    // Make sure entries are not getting disposed.
    maxInactiveAge: 1000 * 60 * 60,
  },
  rewrites() {
    // add a rewrite so the code isn't dead-code eliminated
    return [
      {
        source: '/some-rewrite',
        destination: '/',
      },
    ]
  },
  redirects() {
    return [
      {
        source: '/redirect/me/to-about/:lang',
        destination: '/:lang/

 permanent: false,
      },
      {
        source: '/redirect-query-test/:path',
        destination: '/about?foo=:path',
        permanent: false,
      },
    ]
  },
  images: {
    // Make sure we have sane default CSP, even when SVG is enabled
    dan

about',
        permanent: false,
      },
      {
        source: '/nonexistent',
        destination: '/about',
        permanent: false,
      },
      {
        source: '/shadowed-page',
        destination: '/about',


('next.config evaluation error', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipStart: true,
      skipDeployment: true,
    })
    if (skipped) return

    async function buildAndGetOutput(): Promise<string> {
      const start = next.cliOutput.length
      await next.build()
      return next.cliOutput.slice(start)
    }

    it('should report a helpful error when the config function throws synchronously', async () => {
      a

ect(output).toContain('Invalid typed array length')
      expect(output).toContain(
        'Failed to load next.config.js, see more info here https://nextjs.org/docs/messages/next-config-error'
      )
    })

    it('should report a helpful error when th

wait next.patchFile(
        'next.config.js',
        `
        module.exports = () => {
          return { foo: new Uint8Array(5_000_000_000) }
        }
      `
      )
      const output = await buildAndGetOutput()

      exp


tTestSetup } from 'e2e-utils'
import {
  retry,
  getClientBuildManifestLoaderChunkUrlPath,
} from 'next-test-utils'

describe('Middleware Production Prefetch', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    env: {
      MIDDLEWARE_TEST: 'asdf',
    },
  })

  it('prefetch correctly for unexistent routes', async () => {
    const browser = await next.browser('/')
    await browser.elementByCss('#made-up-link').moveTo()
    await retry(async () => {
      const scripts = await browser.e

age'
      )
      expect(attrs.some((src) => src && src.includes(chunk))).toBe(true)
    })
  })

  it('does not prefetch provided path if it will be rewritten', async () => {
    const browser = await next.browser('/')
    await browser.elementByCss('#ss

lementsByCss('script')
      const attrs = await Promise.all(
        scripts.map((script) => script.getAttribute('src'))
      )
      const chunk = getClientBuildManifestLoaderChunkUrlPath(
        next.testDir,
        '/ssg-p


p from 'fs/promises'
import path from 'path'

describe('500-page app-router-only', () => {
  const { next, isNextStart, isNextDeploy } = nextTestSetup({
    files: __dirname,
  })

  if (isNextDeploy) {
    it('should render app router 500 page when route error', async () => {
      const $ = await next.render$('/route-error')
      expect($('html').attr('id')).toBe('__next_error__')
      // Server errors show "This page couldn\u2019t load"
      expect($('body').text()).toContain('This page couldn\u2019t

'pages', '500.html'),
        'utf8'
      )
      // Not use pages router to generate 500.html
      expect(html).toContain('__next_error__')
      // Server errors show "This page couldn\u2019t load"
      expect(html).toContain('This page couldn\u2019t

load')
    })
  }

  if (isNextStart) {
    it('should use app router to generate 500.html when no pages _error.tsx exists', async () => {
      const html = await fsp.readFile(
        path.join(next.testDir, '.next', 'server',


tTestSetup } from 'e2e-utils'
import fsp from 'fs/promises'
import path from 'path'

describe('500-page - mixed-router-no-custom-pages-error', () => {
  const { next, skipped } = nextTestSetup({
    files: __dirname,
  })

  if (skipped) {
    return
  }

  it('should not use app router global-error for 500.html when no pages _error.tsx exists', async () => {
    const $ = await next.render$('/pages-error')
    const text = $('#__next').text()
    expect(text).toContain('500')
    expect(text).toContain('In

    )
    const pagesManifestJson = JSON.parse(pagesManifest)
    expect(pagesManifestJson).toMatchInlineSnapshot(`
     {
       "/404": "pages/404.html",
       "/_app": "pages/_app.js",
       "/_document": "pages/_document.js",
       "/_error": "pages

ternal Server Error')
  })

  it('pages manifest should only contain 404 and 500', async () => {
    const pagesManifest = await fsp.readFile(
      path.join(next.testDir, '.next', 'server', 'pages-manifest.json'),
      'utf8'


e client'
export default function Page() {
  return (
    <>
      <button
        onClick={async () => {
          const response = await fetch('/app-route', { method: 'OPTIONS' })
          console.log(await response.json())
        }}
      >
        Trigger Options Request (/app route)
      </button>
      <button
        onClick={async () => {
          const response = await fetch('/app-page', { method: 'OPTIONS' })
          console.log(await response.text())
        }}
      >
        Trigger Optio

    Trigger Options Request (/pages page)
      </button>
      <button
        onClick={async () => {
          const response = await fetch('/api/pages-api-handler', {
            method: 'OPTIONS',
          })
          console.log(await response.text(

ns Request (/app page)
      </button>
      <button
        onClick={async () => {
          const response = await fetch('/pages-page', { method: 'OPTIONS' })
          console.log(await response.text())
        }}
      >


from 'e2e-utils'

describe('Static 404 Export', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  // Issue #36855
  // https://github.com/vercel/next.js/issues/36855
  it('only export 404.html when trailingSlash: false', async () => {
    await next.build()

    expect(await next.hasFile('out/404.html')).toBe(true)
    expect(await next.hasFile('out/404.html.html')).toBe(false)
    expect(await next.hasFile('out/404/index.html')).toBe(false)
  })

  it('export 404

wait next.build()
    await next.patchFile(
      'next.config.js',
      `module.exports = (phase) => {
  return {
    output: 'export',
    trailingSlash: false,
  }
}`
    )

    expect(await next.hasFile('out/404/index.html')).toBe(true)
    expect(awa

.html and 404/index.html when trailingSlash: true', async () => {
    await next.patchFile(
      'next.config.js',
      `module.exports = (phase) => {
  return {
    output: 'export',
    trailingSlash: true,
  }
}`
    )
    a


ort { nextTestSetup } from 'e2e-utils'

describe('config validation - fatal errors', () => {
  const { next } = nextTestSetup({
    skipStart: true,
    files: __dirname,
  })

  it('should show warnings first, then throw fatal error', async () => {
    const { exitCode, cliOutput } = await next.build()

    // Build should fail
    expect(exitCode).toBe(1)

    // Should show warnings first
    expect(cliOutput).toContain('Invalid next.config.js options detected')
    expect(cliOutput).toContain(
      "Un

g errors found in next.config.js that must be fixed'
    )
    expect(cliOutput).toContain(
      "Unrecognized key(s) in object: 'invalidOption'"
    )
    expect(cliOutput).toContain('at "images"')
    expect(cliOutput).toContain(
      'These configurat

recognized key(s) in object: 'unknownExperimentalOption', 'anotherUnknownOption'"
    )
    expect(cliOutput).toContain('at "experimental"')

    // Should show fatal error
    expect(cliOutput).toContain(
      'Fatal next confi


{
  webpack(cfg, { isServer, nextRuntime }) {
    const origEntry = cfg.entry
    cfg.entry = async () => {
      const origEntries = await origEntry()

      if (isServer && nextRuntime === 'nodejs') {
        const curEntry = origEntries['pages/_app']
        origEntries['pages/_app'] = [
          path.join(__dirname, 'lib/get-data.js'),
          ...curEntry,
        ]
      }
      return origEntries
    }
    return cfg
  },
  outputFileTracingIncludes: {
    // Full path includes "app" or "pages"

e1': ['./include-me/**/*', 'node_modules/pkg-behind-symlink/*'],
    '/*': ['include-me-global.txt'],
  },
  outputFileTracingExcludes: {
    // Subpaths should also work
    '/index': ['public/exclude-me/**/*'],
    '/route1': ['./public/exclude-me/**/*']

 '/pages/index': ['include-me/**/*'],
    '/app/rout


from 'path'
import { nextTestSetup } from 'e2e-utils'

describe('Babel custom - babel-env', () => {
  const { next } = nextTestSetup({
    files: path.join(__dirname, 'fixtures/babel-env'),
    skipStart: true,
  })

  it('should allow setting babelrc env', async () => {
    const { exitCode } = await next.build()
    expect(exitCode).toBe(0)
  })
})

describe('Babel custom - targets-browsers', () => {
  const { next } = nextTestSetup({
    files: path.join(__dirname, 'fixtures/targets-browsers'),
    skipS

nextTestSetup({
    files: path.join(__dirname, 'fixtures/targets-string'),
    skipStart: true,
  })

  it('should allow setting targets to a string', async () => {
    const { exitCode } = await next.build()
    expect(exitCode).toBe(0)
  })
})

describe

tart: true,
  })

  it('should allow setting targets.browsers', async () => {
    const { exitCode } = await next.build()
    expect(exitCode).toBe(0)
  })
})

describe('Babel custom - targets-string', () => {
  const { next } =


ading request body in middleware', () => {
  const { next } = nextTestSetup({
    files: {
      'middleware.js': `
        const { NextResponse } = require('next/server');

        export default async function middleware(request) {
          if (!request.body) {
            return new Response(null, { status: 400 });
          }

          let json;

          if (!request.nextUrl.searchParams.has("no_reading")) {
            json = await request.json();
          }

          if (request.nextUrl.searchPa

        headers: {
              data: JSON.stringify({ root: true, ...json }),
            },
          })
        }
      `,

      'pages/api/hi.js': `
        export default function hi(req, res) {
          res.json({
            ...req.body,

rams.has("next")) {
            const res = NextResponse.next();
            res.headers.set('x-from-root-middleware', '1');
            return res;
          }

          return new Response(null, {
            status: 200,


import { nextTestSetup } from 'e2e-utils'
import { retry } from 'next-test-utils'

describe('Production Usage', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipDeployment: true,
    })
    if (skipped) return

    it('should navigate forward and back correctly', async () => {
      const browser = await next.browser('/')
      await browser.eval('window.beforeNav = true')
      await browser.elementByCss('#to-another').click()

Nav')).toBe(true)
      await browser.elementByCss('#to-index').click()
      await retry(async () => {
        expect(await browser.hasElementByCssSelector('#to-another')).toBe(true)
      })
      expect(await browser.eval('window.beforeNav')).toBe(true)

   // waitForElement doesn't seem to work properly in safari 10
      await retry(async () => {
        expect(await browser.hasElementByCssSelector('#to-index')).toBe(true)
      })
      expect(await browser.eval('window.before


output
          const firstNodeModules = file.indexOf('/node_modules/')
          const lastNodeModules = file.lastIndexOf('/node_modules/')
          if (firstNodeModules !== lastNodeModules) {
            return file.slice(lastNodeModules)
          }

          return file
        })
    ),
  ]
  result.sort()
  return result
}

async function readNormalizedNFT(next, name) {
  const data = await next.readJSON(name)
  return normalizeNFT(path.join(next.testDir, name, '..'), data.files)
}

// Only run thi

not meant for testing correctness (which is done by the behavioral tests), but as a
// regression test to ensure that some stray `path.join` doesn't cause all of the Next.js package to
// get included.
//
// Also skip alternate React versions, as they woul

s test for Turbopack as it is more conservative (i.e. aggressive) in including
// referenced files and might include too many. (The Webpack snapshots would different slightly from
// the Turbopack ones below.)
//
// This test is


('Middleware validation during build', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipStart: true,
      skipDeployment: true,
    })
    if (skipped) return

    const middlewareError = 'Middleware is returning a response body'

    describe.each([
      {
        title: 'returning a text body',
        code: `export default function () {
              return new Response('this is not allowed')
            }`,
      },
      {

uilding response body with a variable',
        code: `export default function () {
              const body = 'this is not allowed, but hard to detect with AST'
              return new Response(body)
            }`,
      },
      {
        title: 'build

       title: 'building body with JSON.stringify',
        code: `export default function () {
              return new Response(JSON.stringify({ error: 'this is not allowed' }))
            }`,
      },
      {
        title: 'b


 with path prefix', () => {
  let cdnPort: number
  let cdn: http.Server
  let cdnAccessLog: string[] = []

  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
    dependencies: {},
  })

  beforeAll(async () => {
    cdnPort = 0
    cdn = http.createServer((clientReq, clientRes) => {
      const proxyPath = clientReq.url!.slice('/path-prefix'.length)
      cdnAccessLog.push(proxyPath)
      const proxyReq = http.request(
        {
          hostname: 'localhost',
          port: n

localhost:${next.appPort}`
          clientRes.writeHead(proxyRes.statusCode!, proxyRes.headers)
          proxyRes.on('error', (e) => {
            require('console').error(e)
          })
          clientRes.on('error', (e) => {
            require('cons

ext.appPort,
          path: proxyPath,
          method: clientReq.method,
          headers: clientReq.headers,
        },
        (proxyRes) => {
          proxyRes.headers['Access-Control-Allow-Origin'] =
            `http://


from 'e2e-utils'

describe('Invalid Page automatic static optimization', () => {
  const { next } = nextTestSetup({
    files: __dirname,
    skipStart: true,
  })

  it('Fails softly with descriptive error', async () => {
    const { cliOutput } = await next.build()

    expect(cliOutput).toMatch(
      /Build optimization failed: found pages without a React Component as default export in/
    )
    expect(cliOutput).toMatch(/pages\/invalid/)
    expect(cliOutput).toMatch(/pages\/also-invalid/)
  })

  it(

pages/also-valid.js',
      `
      export default function Page() {
        return
hello world

      }
    `
    )
    await next.deleteFile('pages/invalid.js')
    await next.deleteFile('pages/also-invalid.js')
    await next.patchFile(
      'pag

'handles non-error correctly', async () => {
    await next.patchFile(
      'pages/valid.js',
      `
      export default function Page() {
        return
hello world

      }
    `
    )
    await next.patchFile(
      '


 await next.build({
          args: ['--debug-build-paths', 'pages/foo.tsx'],
        })
        expect(buildResult.exitCode).toBe(0)
        expect(buildResult.cliOutput).toBeDefined()

        // Should only build the specified page
        expect(buildResult.cliOutput).toContain('Route (pages)')
        expect(buildResult.cliOutput).toContain('○ /foo')
        // Should not build other pages
        expect(buildResult.cliOutput).not.toContain('○ /bar')
        // Should not build app routes
        expec

ges/bar.tsx'],
        })
        expect(buildResult.exitCode).toBe(0)
        expect(buildResult.cliOutput).toBeDefined()

        // Should build both specified pages
        expect(buildResult.cliOutput).toContain('Route (pages)')
        expect(buildRe

t(buildResult.cliOutput).not.toContain('Route (app)')
      })

      it('should build multiple pages routes', async () => {
        const buildResult = await next.build({
          args: ['--debug-build-paths', 'pages/foo.tsx,pa


execSync } from 'child_process'

const dependencies = {
  'es-check': '9.6.4',
  browserslist: '4.28.1',
}

describe('escheck-output', () => {
  describe('es2020', () => {
    let browserslist = [
      'chrome 64',
      'edge 79',
      'firefox 67',
      'opera 51',
      'safari 12',
    ]
    const { next } = nextTestSetup({
      files: __dirname,
      dependencies,
      packageJson: {
        browserslist,
      },
    })

    it('should downlevel JS', () => {
      let esCheckOutput = execSync(

ult browserslist', () => {
    let browserslist = ['chrome 111', 'edge 111', 'firefox 111', 'safari 16.4']

    const { next } = nextTestSetup({
      files: __dirname,
      dependencies,
      packageJson: {
        browserslist,
      },
    })

    it(

       'node_modules/.bin/es-check es2020 ".next/static/**/*.js" --noCache',
        { cwd: next.testDir, encoding: 'utf8' }
      )

      expect(esCheckOutput).toContain('info: ✓ ES-Check passed!')
    })
  })

  describe('defa


from 'e2e-utils'
import { fetchViaHTTP } from 'next-test-utils'

describe('emitDecoratorMetadata SWC option', () => {
  const { next } = nextTestSetup({
    files: join(__dirname, 'app'),
    dependencies: {
      'reflect-metadata': '0.1.13',
      'path-to-regexp': '6.2.0',
      tsyringe: '4.6.0',
    },
  })

  it('should compile with emitDecoratorMetadata enabled', async () => {
    let browser: Playwright
    try {
      browser = await next.browser('/')
      const message = await browser.elementByCs

llo, world!')
    } finally {
      if (browser) {
        await browser.close()
      }
    }
  })

  it('should compile with emitDecoratorMetadata enabled for API', async () => {
    const res = await fetchViaHTTP(next.url, '/api/something')
    expect(r

s('#message').text()

      expect(message).toBe('He


'childProcesses', false],
] as const)(
  'turbopack-node-backend (%s)',
  (turbopackPluginRuntimeStrategy, expectSamePid) => {
    const { next, isTurbopack } = nextTestSetup({
      files: __dirname,
      env: {
        TEST_TURBOPACK_PLUGIN_RUNTIME_STRATEGY: turbopackPluginRuntimeStrategy,
      },
    })

    const itOnlyTurbopack = isTurbopack ? it : it.skip

    itOnlyTurbopack('should match expected loader pid behavior', async () => {
      const response = await next.fetch('/api/pid')
      expect(r

response.json()
      expect(data.buildPid).toBeDefined()
      expect(data.loaderPid).toBeDefined()

      if (expectSamePid) {
        expect(data.loaderPid).toBe(data.buildPid)
      } else {
        expect(data.loaderPid).not.toBe(data.buildPid)

esponse.status).toBe(200)

      const data = await


ster)
//   --host-target  Share host target/ dir with container for caching
//   --rebuild      Force Docker image rebuild
//   --test         Smoke-test built binaries (native arch only)
//   filter         Substring match on target name (e.g. "musl", "x86_64")

const { execFileSync } = require('child_process')
const path = require('path')
const fs = require('fs')
const os = require('os')

const REPO_ROOT = path.resolve(__dirname, '..')
const DOCKER_IMAGE = 'next-swc-builder:latest'

const TARGETS = [
  {

gnu',
  },
  {
    target: 'x86_64-unknown-linux-musl',
    arch: 'x86_64',
    abi: 'musl',
    napiPlatform: 'linux-x64-musl',
  },
  {
    target: 'aarch64-unknown-linux-musl',
    arch: 'aarch64',
    abi: 'musl',
    napiPlatform: 'linux-arm64-musl',

    target: 'x86_64-unknown-linux-gnu',
    arch: 'x86_64',
    abi: 'gnu',
    napiPlatform: 'linux-x64-gnu',
  },
  {
    target: 'aarch64-unknown-linux-gnu',
    arch: 'aarch64',
    abi: 'gnu',
    napiPlatform: 'linux-arm64-


h')
const { spawn } = require('child_process')
const fs = require('fs/promises')

const cwd = process.cwd()

async function main() {
  const tarballs = await fs.readdir(path.join(cwd, 'public'))
  const nextTarball = tarballs.find((item) => !item.includes('-swc'))

  await fs.rename(
    path.join(cwd, 'public', nextTarball),
    path.join(cwd, nextTarball)
  )

  await new Promise((resolve, reject) => {
    const child = spawn('tar', ['-xf', nextTarball], {
      stdio: 'inherit',
      shell: true,

arsedPackageJson = JSON.parse(
    await fs.readFile(unpackedPackageJson, 'utf8')
  )
  const { optionalDependencies } = parsedPackageJson

  for (const key of Object.keys(optionalDependencies)) {
    optionalDependencies[key] = optionalDependencies[key].r

cwd,
    })

    child.on('exit', (code) => {
      if (code) {
        return reject(`Failed with code ${code}`)
      }
      resolve()
    })
  })

  const unpackedPackageJson = path.join(cwd, 'package/package.json')
  const p


ENV = 'production'

// Change this to 'experimental' to opt into the React experimental channel (needed for server actions, ppr)
process.env.__NEXT_PRIVATE_PREBUNDLED_REACT = 'next'

let currentNode = null

let outliers = []

const chalk = {
  yellow: (str) => `\x1b[33m${str}\x1b[0m`,
  green: (str) => `\x1b[32m${str}\x1b[0m`,
}

if (process.env.LOG_REQUIRE) {
  const originalCompile = require('module').prototype._compile

  require('module').prototype._compile = function (_content, filename) {
    let pare

 const end = performance.now()

    currentNode.totalDuration = end - start
    currentNode.selfDuration = currentNode.children.reduce(
      (acc, child) => acc - child.selfDuration,
      currentNode.totalDuration
    )

    parent?.children.push(current

nt = currentNode

    currentNode = {
      id: filename,
      selfDuration: 0,
      totalDuration: 0,
      children: [],
    }

    const start = performance.now()
    const result = originalCompile.apply(this, arguments)


les: {
      'public/vercel.svg':
        '<svg width="24" height="24" xmlns="http://www.w3.org/2000/svg"/>',
      'components/comp.js': `
          export default function Comp() {
            return
Hello Dynamic
;
          }
        `,
      'styles/index.module.css': '.home { color: orange }',
      'pages/index.js': `
          import dynamic from "next/dynamic";
          import Image from "next/image";
          import img from "../public/vercel.svg";
          import styles from "../styles

nt.woff2" });

          const Comp = dynamic(() => import("../components/comp"), {
            loading: () =>
Loading...
,
          });

          export default function Page() {
            return <>
              <Comp />
              <Image

/index.module.css";
          import localFont from "next/font/local";
          import { Inter } from "next/font/google";

          const inter = Inter({ subsets: ["latin"] });
          const myFont = localFont({ src: "./my-fo


tTestSetup } from 'e2e-utils'

describe('next/jest newLinkBehavior', () => {
  const { next } = nextTestSetup({
    files: {
      'pages/index.jsx': `
        import Link from 'next/link'

        export default function Page() {
          return <Link href='https://example.com'>
Hello World!
</Link>
        }
      `,
      'test/index.test.jsx': `
        import { render, screen, act } from '@testing-library/react'
        import Page from '../pages/index'

        it('Link', () => {
          r

st = require('next/jest')
        const createJestConfig = nextJest({ dir: './' })
        module.exports = createJestConfig({
          testEnvironment: 'jest-environment-jsdom',
        })
      `,
    },
    dependencies: {
      jest: '29.7.0',
      '

ender(<Page />)

          const link = screen.getByRole('link', { name: 'Hello World!' })
          expect(link.getAttribute('href')).toBe('https://example.com')
        })
      `,
      'jest.config.js': `
        const nextJe


import path from 'path'

const appDir = path.join(__dirname, 'app')

// react-relay is not compatible with React 19 and therefore Next.js 15
describe.skip('next/jest', () => {
  nextTestSetup({
    files: {
      components: new FileRef(path.join(appDir, 'components')),
      pages: new FileRef(path.join(appDir, 'pages')),
      'tests/entry.test.tsx': `
      import { render, waitFor } from '@testing-library/react'
      import { RelayEnvironmentProvider } from 'react-relay'
      import { createMockEnviro

eateMockEnvironment()

          const { getByText } = render(
            <RelayEnvironmentProvider environment={environment}>
              <Page />
            </RelayEnvironmentProvider>
          )

          environment.mock.resolveMostRe

nment, MockPayloadGenerator } from 'relay-test-utils'

      import Page from '@/pages'

      describe('test graphql tag transformation', () => {
        it('should work', async () => {
          let environment = cr


ce80db9f1b8ab>>
 * @lightSyntaxTransform
 * @nogrep
 */

/* tslint:disable */
/* eslint-disable */
// @ts-nocheck

import { ConcreteRequest, Query } from 'relay-runtime'
export type pagesQuery$variables = {}
export type pagesQueryVariables = pagesQuery$variables
export type pagesQuery$data = {
  readonly viewer: {
    readonly user: {
      readonly id: string
      readonly name: string
    }
  }
}
export type pagesQueryResponse = pagesQuery$data
export type pagesQuery = {
  variables: pagesQueryVariables

l,
      args: null,
      concreteType: 'User',
      kind: 'LinkedField',
      name: 'user',
      plural: false,
      selections: [
        v0 /*: any*/,
        {
          alias: null,
          args: null,
          kind: 'ScalarField',
          n

  response: pagesQuery$data
}

const node: ConcreteRequest = (function () {
  var v0 = {
      alias: null,
      args: null,
      kind: 'ScalarField',
      name: 'id',
      storageKey: null,
    },
    v1 = {
      alias: nul


th from 'path'
import type { NextAdapter } from 'next'

import { FILES } from './files'

// Webpack itself isn't deterministic
;(process.env.IS_TURBOPACK_TEST ? describe : describe.skip)(
  'adapter-content-hashes',
  () => {
    describe.each([
      { name: 'standard', files: FILES.standard },
      { name: 'cache components', files: FILES.cacheComponents },
    ])('for $name', ({ name, files }) => {
      const { next } = nextTestSetup({
        files,
        env: {
          NEXT_ADAPTER_PATH: path.joi

]>[0] = await next.readJSON(
          'build-complete.json'
        )

        function validateOutput(output: {
          runtime?: 'edge' | 'nodejs'
          filePath: string
          assets?: Record<string, string>
          assetsHashes?: Record<str

n(__dirname, './my-adapter.mjs'),
        },
      })

      it('should emit server-side hashes to adapter', async () => {
        const {
          repoRoot,
          outputs,
        }: Parameters<NextAdapter['onBuildComplete'


import path from 'path'

export const FILES = {
  standard: {
    app: new FileRef(path.join(__dirname, 'standard', 'app')),
    pages: new FileRef(path.join(__dirname, 'standard', 'pages')),
    public: new FileRef(path.join(__dirname, 'standard', 'public')),
    'instrumentation.ts': new FileRef(
      path.join(__dirname, 'standard', 'instrumentation.ts')
    ),
    'middleware.ts': new FileRef(
      path.join(__dirname, 'standard', 'middleware.ts')
    ),
    'next.config.js': new FileRef(
      path.

  },
  cacheComponents: {
    app: new FileRef(path.join(__dirname, 'cache-components', 'app')),
    'next.config.js': new FileRef(
      path.join(__dirname, 'cache-components', 'next.config.js')
    ),
    'proxy.ts': new FileRef(
      path.join(__dirn

join(__dirname, 'standard', 'next.config.js')
    ),


waitFor } from 'next-test-utils'

describe('SSG Prerender No Revalidate', () => {
  const { next } = nextTestSetup({
    files: __dirname,
  })

  function runTests(route: string) {
    const pagePath = route === '/' ? '/index' : route

    it(`[${route}] should not revalidate when set to false`, async () => {
      const fileName = `.next/server/pages${pagePath}.html`
      const initialHtml = await next.render(route)
      const initialFileHtml = await next.readFile(fileName)

      let newHtml = await ne

)
      expect(await next.readFile(fileName)).toBe(initialFileHtml)

      await waitFor(500)

      newHtml = await next.render(route)
      expect(initialHtml).toBe(newHtml)
      expect(await next.readFile(fileName)).toBe(initialFileHtml)

      expect(

xt.render(route)
      expect(initialHtml).toBe(newHtml)
      expect(await next.readFile(fileName)).toBe(initialFileHtml)

      await waitFor(500)

      newHtml = await next.render(route)
      expect(initialHtml).toBe(newHtml


xtTestSetup } from 'e2e-utils'
import { waitFor } from 'next-test-utils'

describe('route cancel via CSS', () => {
  describe('production mode', () => {
    const { next, skipped } = nextTestSetup({
      files: __dirname,
      skipDeployment: true,
    })
    if (skipped) return

    it('should cancel slow page loads on re-navigation', async () => {
      const browser = await next.browser('/')

      await browser.elementByCss('#link-1').click()
      await waitFor(3000)
      expect(await browser.hasEle

await browser.elementByCss('#link-2').click()
      await waitFor(3000)

      const text2 = await browser.elementByCss('#page-text').text()
      expect(text2).toMatch(/2/)
      expect(await browser.eval('window.routeCancelled')).toBe('yes')
    })
  })


 dev server bundle.
 *
 * Usage:
 *   node scripts/analyze-bundle.js [options]
 *
 * Options:
 *   --open          Open the report in browser (default: false)
 *   --verbose       Show detailed module reasons
 *   --json          Also output stats.json file
 *   --list-modules  List all bundled modules to console
 *   --list-externals List all externalized modules
 */

const { execSync } = require('child_process')
const path = require('path')
const fs = require('fs')

// Parse arguments
const args = process

Externals = hasFlag('list-externals')

const nextDir = path.join(__dirname, '..', 'packages', 'next')
const bundlePath = path.join(
  nextDir,
  'dist/compiled/dev-server/start-server.js'
)
const reportPath = path.join(
  nextDir,
  'dist/compiled/dev-serv

.argv.slice(2)
const hasFlag = (name) => args.includes(`--${name}`)

const openBrowser = hasFlag('open')
const verbose = hasFlag('verbose')
const outputJson = hasFlag('json')
const listModules = hasFlag('list-modules')
const list


: execOriginal } = require('child_process')
const {
  createSignedCommit,
  upsertBranchRef,
} = require('./github-utils/signed-commit')

const exec = promisify(execOriginal)

const {
  RELEASE_GITHUB_TOKEN = '',
  PR_GITHUB_TOKEN = '',
  RELEASE_GITHUB_APP_SLUG = '',
  RELEASE_GITHUB_APP_USER_ID = '',
  SCRIPT = '',
  BRANCH_NAME = 'unknown',
  PR_TITLE = 'Automated update',
  PR_BODY = '',
} = process.env

if (!RELEASE_GITHUB_TOKEN) {
  console.log('missing RELEASE_GITHUB_TOKEN env')
  process.exit(1)
}
i

 console.log('missing RELEASE_GITHUB_APP_USER_ID env')
  process.exit(1)
}
if (!SCRIPT) {
  console.log('missing SCRIPT env')
  process.exit(1)
}

const REPO_OWNER = 'vercel'
const REPO_NAME = 'next.js'

async function main() {
  const octokit = new Octoki

f (!PR_GITHUB_TOKEN) {
  console.log('missing PR_GITHUB_TOKEN env')
  process.exit(1)
}
if (!RELEASE_GITHUB_APP_SLUG) {
  console.log('missing RELEASE_GITHUB_APP_SLUG env')
  process.exit(1)
}
if (!RELEASE_GITHUB_APP_USER_ID) {


=PATH   Test project directory (default: /private/tmp/next-boot-test)
 *   --bundled         Use bundled dev server (default)
 *   --unbundled       Use unbundled dev server
 *   --compare         Run both bundled and unbundled for comparison
 *   --turbopack       Use Turbopack (default)
 *   --webpack         Use Webpack
 */

const { spawn, execSync } = require('child_process')
const path = require('path')
const fs = require('fs')

// Parse arguments
const args = process.argv.slice(2)
const getArg = (name

s', '5'), 10)
const testDir = getArg('test-dir', '/private/tmp/next-boot-test')
const compare = hasFlag('compare')
const useWebpack = hasFlag('webpack')
const bundlerFlag = useWebpack ? '--webpack' : '--turbopack'

const nextDir = path.join(__dirname, '..'

, defaultValue) => {
  const arg = args.find((a) => a.startsWith(`--${name}=`))
  return arg ? arg.split('=')[1] : defaultValue
}
const hasFlag = (name) => args.includes(`--${name}`)

const iterations = parseInt(getArg('iteration


t fs = require('fs')
const path = require('path')
const globOrig = require('glob')
const { promisify } = require('util')
const glob = promisify(globOrig)

function collectPaths(routes, paths = []) {
  for (const route of routes) {
    if (route.path && !route.redirect) {
      paths.push(route.path)
    }

    if (route.routes) {
      collectPaths(route.routes, paths)
    }
  }
}

async function main() {
  const manifest = 'errors/manifest.json'
  let hadError = false

  const dir = path.dirname(manifest)

ilter(
    (file) => !paths.includes(`/${file}`) && file !== 'errors/template.md'
  )

  if (missingFiles.length) {
    hadError = true
    console.log(`Missing paths in ${manifest}:\n${missingFiles.join('\n')}`)
  } else {
    console.log(`No missing path

  const files = await glob(path.join(dir, '**/*.md'))

  const manifestData = JSON.parse(await fs.promises.readFile(manifest, 'utf8'))

  const paths = []
  collectPaths(manifestData.routes, paths)

  const missingFiles = files.f


 tarballDirectory = path.join(os.tmpdir(), 'vercel-nextjs-preview-tarballs'),
    baseUrlArg,
  ] = process.argv.slice(2)
  const baseUrl = baseUrlArg || 'https://vercel-packages.vercel.app/next'
  const repoRoot = path.resolve(__dirname, '..')

  await fs.mkdir(tarballDirectory, { recursive: true })

  // The preview version is set in packages/next/package.json by
  // scripts/set-preview-version.js before the build step.
  const nextPackageJson = JSON.parse(
    await fs.readFile(path.join(repoRoot, 'pack

= (await fs.readdir(nativePackagesDir)).filter(
    (name) => !name.startsWith('.')
  )

  console.info(`Creating tarballs for next-swc packages`)
  const nextSwcPackageNames = new Set()
  await Promise.all(
    platforms.map(async (platform) => {
      co

ages/next/package.json'), 'utf8')
  )
  const version = nextPackageJson.version
  console.info(`Designated version: ${version}`)

  const nativePackagesDir = path.join(repoRoot, 'crates/next-napi-bindings/npm')
  const platforms