Pre-requisites for rspack local testing
Before running pnpm test-rspack, you must: build @next/rspack-core by running pnpm install and pnpm build in rspack directory; link to packages/next-rspack by running pnpm link ../../rspack from packages/next-rspack; return to root and run pnpm install; finally run pnpm test-rspack. After modifying Rust code under rspack/, re-run pnpm build from the rspack directory.
rspack test commands
Test commands for rspack: pnpm test-rspack runs full test suite using Rspack compiler; pnpm test-dev-rspack runs development mode tests; pnpm test-start-rspack runs production mode tests; pnpm run with-rspack pnpm testonly -- <test-pattern> runs specific tests. All test commands set environment variables NEXT_RSPACK=1 and NEXT_USE_RSPACK=1 via with-rspack.
Test OpenTelemetry instrumentation locally
To test OpenTelemetry traces locally, use an OpenTelemetry collector with a compatible backend. Vercel provides an OpenTelemetry dev environment setup. When working correctly, you should see a root server span labeled as 'GET /requested/pathname' with all other spans nested under it.
Test offline behavior with production build
Test the useOffline feature with next build && next start. Dev mode is not a reliable reference for offline behavior. Use Chrome DevTools Network > Offline, Firefox Network Monitor throttling menu, or real-world tests like toggling airplane mode, disconnecting WiFi, or unplugging the network cable.
Auditing checklist for use client files
When auditing a Next.js project's 'use client' files, check: (1) Are Component props expecting private data? (2) Are type signatures overly broad?
Auditing checklist for Data Access Layer
When auditing a Next.js project's Data Access Layer, verify: (1) An established practice for an isolated Data Access Layer exists, (2) Database packages and environment variables are not imported outside the Data Access Layer.
Auditing checklist for use server files
When auditing a Next.js project's 'use server' files, verify: (1) Are Action arguments validated in the action or inside the Data Access Layer? (2) Is the user re-authorized inside the action? (3) Does the action check ownership of the resource (authorization, not just authentication)? (4) Are return values filtered to only what the client needs? (5) Is database access delegated to a server-only Data Access Layer?
Auditing checklist for dynamic route parameters
When auditing a Next.js project, pay special attention to folders with brackets [param] as they represent user input. Verify that params are properly validated.
Auditing checklist for proxy and route files
proxy.ts and route.ts files have significant power and should receive extra time during audits using traditional security techniques. Perform Penetration Testing or Vulnerability Scanning regularly or in alignment with the team's software development lifecycle.
Using instant() helper for e2e testing
The @next/playwright package includes an instant() helper for testing that scopes assertions to the UI immediately available on navigation. Use page.goto() to test the static UI from the document response on initial page load, and click a Link to test the destination's prefetched UI on client navigation.
Enable testing API in production builds
To run instant() tests in CI against a production build, set experimental.exposeTestingApiInProductionBuild: true in next.config.ts so next start exposes the testing API.
Example: Instant navigation e2e test with Playwright
```typescript
import { test, expect } from '@playwright/test'
import { instant } from '@next/playwright'
test.describe('Product page (/store/[slug])', () => {
test('is instant on an initial page load', async ({ page, baseURL }) => {
await instant(
page,
async () => {
await page.goto('/store/hats')
await expect(page.locator('h1')).toContainText('Baseball Cap')
await expect(page.getByText('In stock')).toHaveCount(0)
},
{ baseURL }
)
await expect(page.getByText('In stock')).toBeVisible()
})
test('is instant on a client navigation', async ({ page }) => {
await page.goto('/store/shoes')
await instant(page, async () => {
await page.click('a[href="/store/hats"]')
await page.waitForURL((url) => url.pathname === '/store/hats')
await expect(page.locator('h1')).toContainText('Baseball Cap')
await expect(page.getByText('In stock')).toHaveCount(0)
})
await expect(page.getByText('In stock')).toBeVisible()
})
})
```
This shows testing instant navigation for both initial page load (with baseURL) and client navigation (with URL wait before assertion).
Pass baseURL to instant() when page.goto() is first navigation
Pass Playwright's baseURL to instant() when page.goto() is the first navigation. The helper needs the origin before requesting the document.
Navigation Inspector in Next.js DevTools
The Navigation Inspector in the Next.js DevTools freezes the page at its initial loading state, showing the static shell on direct visits and the prefetched destination on client navigations. It is available when Cache Components is enabled. Use Pause on navigations to freeze the page and inspect the shell.
Wait for destination URL before asserting in instant() client navigations
For client navigations in instant() tests, wait for the destination URL before asserting on its UI. Otherwise, a shared selector can match the source page before the destination commits. If the prefetched destination cannot commit, the URL wait times out and the test fails.
Running tests with Turbopack
To run the test suite using Turbopack, use the -turbo version of the npm script: pnpm test-dev-turbo test/e2e/app-dir/app/
Running tests against both Turbopack and Webpack
To run a test against both Turbopack and Webpack, use Jest's --projects flag: pnpm test-dev test/e2e/app-dir/app/ --projects jest.config.*
Running deploy tests locally with NEXT_TEST_VERSION
To run deploy tests locally against a specific commit, use the NEXT_TEST_VERSION environment variable: NEXT_TEST_VERSION=https://vercel-packages.vercel.app/next/commits/<commitSha>/next pnpm test-deploy <path-to-test>
Creating local Next.js builds for integration testing
To locally generate builds for each package in the repository, use: pnpm pack-next. You can specify a project directory with: pnpm pack-next --project ~/my-project/
Creating tarballs for Next.js testing
To create tarballs for testing, use: pnpm pack-next --tar. The tarballs will be written to a tarballs directory in the root of the repository.
Creating deployable tarballs for projects
To create tarballs that can be deployed with a project, use: pnpm pack-next --project ~/my-project/ --deployable-tar. This writes tarballs to a tarballs directory next to the patched project package.json and uses relative file: references.
Using preview builds from specific commits
To use next from a specific commit, include the commit SHA in package.json: { "dependencies": { "next": "https://vercel-packages.vercel.app/next/commits/188f76947389a27e9bcff8ebf9079433679256a7/next" } }. Dependencies are automatically rewritten to use the same commit SHA.
Using preview builds from pull requests
To use next from a specific Pull Request, include the PR number in package.json: { "dependencies": { "next": "https://vercel-packages.vercel.app/next/prs/66445/next" } }
Test files should be written in TypeScript
All new test suites should be written in TypeScript either .ts (or .tsx for unit tests). This will help ensure smaller issues in tests are caught that could cause flaky or incorrect tests.
Using pnpm new-test to create tests
You can set up a new test using pnpm new-test which will start from a template related to the test type. It automatically uses nextTestSetup for appropriate test types.
Building project before running tests
Before you start to run tests, you need to build the project first using: pnpm build
Deploy tests verification scope
Deploy tests verify that Next.js works correctly when deployed to Vercel. These tests are part of the e2e test suite and run against real Vercel deployments.
Best practice: test fails without fix
When applying a fix, ensure the test fails without the fix. This makes sure the test will properly catch regressions.
Main types of tests in Next.js testing strategy
The main types of tests in Next.js testing strategy are: e2e tests (end-to-end, runs against multiple modes and deployments), development tests (runs against next dev), production tests (runs against next start), integration tests (historical, for misc checks), and unit tests (fast, isolated utility tests).
nextTestSetup for e2e and isolated tests
For e2e, development, and production tests, the nextTestSetup utility should be used. This creates an isolated Next.js installation in the system's temp folder to ensure nothing in the monorepo is relied on accidentally. A server is started on a random port, tests run against it, then the server is destroyed and temp files are deleted. All this logic is handled by nextTestSetup automatically.
Running tests in production mode
To run tests in production mode (next build and next start), use the command: pnpm test-start test/e2e/app-dir/app/
Running tests in development mode
To run tests in development mode (next dev), use the command: pnpm test-dev test/e2e/app-dir/app/
Debugging tests with browser visibility
To debug a particular test and see the browser window open, replace pnpm test-start with pnpm testonly-start: pnpm testonly-start test/e2e/app-dir/app/
Best practice: wait for conditions in tests
When checking for a condition that might take time, ensure it is waited for either using the browser waitForElement or using the check util in next-test-utils.
NEXT_TEST_SKIP_CLEANUP environment variable
Use NEXT_TEST_SKIP_CLEANUP=1 to prevent deleting the temp folder created for a test. This allows you to run pnpm debug while inside the temp folder to debug the fully set-up test project.
NEXT_SKIP_ISOLATE environment variable
Use NEXT_SKIP_ISOLATE=1 if the test doesn't need to be installed to debug, and it will run inside the Next.js repo instead of the temp directory. This can reduce test times locally but is not compatible with all tests.
NEXT_TEST_MODE environment variable
The NEXT_TEST_MODE env variable allows toggling specific test modes for the e2e folder, useful when not using pnpm test-dev or pnpm test-start directly.
NEXT_TEST_DEPLOY_URL environment variable
Use NEXT_TEST_DEPLOY_URL with pnpm test-deploy to skip the Vercel deploy step and run deploy-mode assertions against an existing deployment URL.
NEXT_TEST_PREFER_OFFLINE environment variable
Use NEXT_TEST_PREFER_OFFLINE=1 while testing to configure the package manager to include the --prefer-offline argument during test setup. This is helpful when running tests in internet-restricted environments such as planes or public Wi-Fi.
Attaching Chrome debugger to Next.js in tests
To attach the Chrome debugger to Next during tests, modify the nextTestSetup call to pass --inspect to next. Consider also setting NEXT_E2E_TEST_TIMEOUT=0. Example: const { next } = nextTestSetup({ ...startArgs: ['--inspect'], })
NEXT_TEST_TRACE environment variable for profiling
Add NEXT_TEST_TRACE=1 to enable test profiling. It is useful for improving the testing infrastructure.
Testing the error code SWC plugin
Run 'cargo test' inside the crates/next-error-code-swc-plugin directory to test the plugin.