Script Component

Summary: API reference for the Next.js Script component (next/script), covering its props, loading strategies, event handlers, and version history.

Script Component

This API reference will help you understand how to use [props](#props) available for the Script Component. For features and usage, please see the [Optimizing Scripts](/docs/app/guides/scripts) page.

import Script from 'next/script'

export default function Dashboard() {
  return (
    <>
      <Script src="https://example.com/script.js" />
    </>
  )
}

Props

Here's a summary of the props available for the Script Component:

| Prop | Example | Type | Required |
| --- | --- | --- | --- |
| `src` | `src="http://example.com/script"` | String | Required…

Required Props

The `<Script />` component requires the following properties.

src

A path string specifying the URL of an external script. This can be either an absolute external URL or an internal path. The `src` property is required unless an inline script is used.

Optional Props

The `<Script />` component accepts a number of additional properties beyond those which are required.

strategy

The loading strategy of the script. There are four different strategies that can be used:

- `beforeInteractive`: Load before any Next.js code and before any page hydration occurs.
-…

beforeInteractive

Scripts that load with the `beforeInteractive` strategy are injected into the initial HTML from the server, downloaded before any Next.js module, and executed in the order they are placed.

Scripts…

import Script from 'next/script'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>
        {children}…

afterInteractive

Scripts that use the `afterInteractive` strategy are injected into the HTML client-side and will load after some (or all) hydration occurs on the page. **This is the default strategy** of the Script…

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="afterInteractive" />
    </>
  )
}

lazyOnload

Scripts that use the `lazyOnload` strategy are injected into the HTML client-side during browser idle time and will load after all resources on the page have been fetched. This strategy should be…

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="lazyOnload" />
    </>
  )
}

worker

> **Warning:** The `worker` strategy is not yet stable and does not yet work with the App Router. Use with caution.

Scripts that use the `worker` strategy are off-loaded to a web worker in order to…

module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}

import Script from 'next/script'

export default function Home() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="worker" />
    </>
  )
}

onLoad

> **Warning:** `onLoad` does not yet work with Server Components and can only be used in Client Components. Further, `onLoad` can't be used with `beforeInteractive` – consider using `onReady`…

'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script…

onReady

> **Warning:** `onReady` does not yet work with Server Components and can only be used in Client Components.

Some third-party scripts require users to run JavaScript code after the script has…

'use client'

import { useRef } from 'react'
import Script from 'next/script'

export default function Page() {
  const mapRef = useRef()

  return (
    <>

…

onError

> **Warning:** `onError` does not yet work with Server Components and can only be used in Client Components. `onError` cannot be used with the `beforeInteractive` loading strategy.

Sometimes it is…

'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {…

Version History

| Version | Changes |
| --- | --- |
| `v13.0.0` | `beforeInteractive` and `afterInteractive` is modified to support `app`. |
| `v12.2.4` | `onReady` prop added. |
| `v12.2.2` | Allow `next/script`…

strategy

The loading strategy of the script. One of `beforeInteractive`, `afterInteractive`, `lazyOnload`, or `worker`.

onLoad

Executes JavaScript code after the script has finished loading. Only works with `afterInteractive` or `lazyOnload` strategies. Cannot be used with Server Components or `beforeInteractive`.

onReady

Executes JavaScript code after the script's load event when it first loads and after every subsequent component re-mount. Cannot be used with Server Components.

onError

Handles errors when a script fails to load. Cannot be used with Server Components or the `beforeInteractive` loading strategy.


Configuration

Summary: Overview page for Next.js configuration options, linking to documentation for next.config.js, TypeScript, and ESLint.

Configuration

next.config.js: Learn how to configure your application with next.config.js.

TypeScript: Next.js provides a TypeScript-first development experience for building your React application.

ESLint:…


ESLint Plugin

Summary: Explains how to configure ESLint for Next.js using eslint-config-next, including setup, available rules, examples, and migrating existing ESLint configurations.

ESLint Plugin

Next.js provides an ESLint configuration package, [`eslint-config-next`](https://www.npmjs.com/package/eslint-config-next), that makes it easy to catch common issues in your application. It includes…

Setup ESLint

Get linting working quickly with the ESLint CLI (flat config):

import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'

const eslintConfig = defineConfig([
  ...nextVitals,
  // Override default…

Reference

The `eslint-config-next` package includes the `recommended` rule-sets from the following ESLint plugins:

- [`eslint-plugin-react`](https://www.npmjs.com/package/eslint-plugin-react)
-…

Rules

The `@next/eslint-plugin-next` rules included are:

| Enabled in recommended config | Rule | Description |
| --- | --- | --- |
|  |…

Examples

Specifying a root directory within a monorepo

If you're using `@next/eslint-plugin-next` in a project where Next.js isn't installed in your root directory (such as a monorepo), you can tell `@next/eslint-plugin-next` where to find your Next.js…

import { defineConfig } from 'eslint/config'
import eslintNextPlugin from '@next/eslint-plugin-next'

const eslintConfig = defineConfig([
  {
    files: ['**/*.{js,jsx,ts,tsx}'],
    plugins: {…

Disabling rules

If you would like to modify or disable any rules provided by the supported plugins (`react`, `react-hooks`, `next`), you can directly change them using the `rules` property in your…

import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'

const eslintConfig = defineConfig([
  ...nextVitals,
  {
    rules: {…

With Core Web Vitals

Enable the `eslint-config-next/core-web-vitals` configuration in your ESLint config.

`eslint-config-next/core-web-vitals` upgrades certain lint rules in `@next/eslint-plugin-next` from warnings to…

With TypeScript

In addition to the Next.js ESLint rules, `create-next-app --typescript` will also add TypeScript-specific lint rules with `eslint-config-next/typescript` to your config:

Those rules are based on…

import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
import nextTs from 'eslint-config-next/typescript'

const eslintConfig =…

With Prettier

ESLint also contains code formatting rules, which can conflict with your existing [Prettier](https://prettier.io/) setup. We recommend including…

import { defineConfig, globalIgnores } from 'eslint/config'
import nextVitals from 'eslint-config-next/core-web-vitals'
import prettier from 'eslint-config-prettier/flat'

const eslintConfig =…

Running lint on staged files

If you would like to use ESLint with [lint-staged](https://github.com/okonet/lint-staged) to run the linter on staged git files, add the following to the `.lintstagedrc.js` file in the root of your…

const path = require('path')

const buildEslintCommand = (filenames) =>
  `eslint --fix ${filenames
    .map((f) => `"${path.relative(process.cwd(), f)}"`)
    .join(' ')}`

module.exports = {…

Migrating existing config

If you already have ESLint configured in your application, there are two approaches to integrate Next.js linting rules, depending on your setup.

Using the plugin directly

Use `@next/eslint-plugin-next` directly if you have any of the following already configured:

- Conflicting plugins installed separately or through another config (such as `airbnb` or `react-app`):…

import { defineConfig } from 'eslint/config'
import nextPlugin from '@next/eslint-plugin-next'

const eslintConfig = defineConfig([
  // Your other configurations...
  {
    files:…

Adding to existing config

If you're adding Next.js to an existing ESLint setup, spread the Next.js config into your array:

When you spread `...nextConfig`, you're adding multiple config objects that include file patterns,…

import nextConfig from 'eslint-config-next/core-web-vitals'
// Your other config imports...

const eslintConfig = [
  // Your other configurations...
  ...nextConfig,
]

export default eslintConfig

Version History

| Version | Changes |
| --- | --- |
| `v16.0.0` | `next lint` and the `eslint` next.config.js option were removed in favor of the ESLint CLI. A…


next.config.js

Summary: Overview of Next.js configuration via next.config.js, including setup, ECMAScript modules, function-based configuration, TypeScript support, and a list of all available configuration options.

next.config.js

Next.js can be configured through a `next.config.js` file in the root of your project directory (for example, by `package.json`) with a default export.

// @ts-check

/** @type {import('next').NextConfig} */
const nextConfig = {
  /* config options here */
}

module.exports = nextConfig

ECMAScript Modules

`next.config.js` is a regular Node.js module, not a JSON file. It gets used by the Next.js server and build phases, and it's not included in the browser build.

If you need [ECMAScript…

// @ts-check

/**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  /* config options here */
}

export default nextConfig

Configuration as a Function

You can also use a function:

// @ts-check

export default (phase, { defaultConfig }) => {
  /**
   * @type {import('next').NextConfig}
   */
  const nextConfig = {
    /* config options here */
  }
  return nextConfig
}

Async Configuration

Since Next.js 12.1.0, you can use an async function:

// @ts-check

module.exports = async (phase, { defaultConfig }) => {
  /**
   * @type {import('next').NextConfig}
   */
  const nextConfig = {
    /* config options here */
  }
  return nextConfig
}

Phase

`phase` is the current context in which the configuration is loaded. You can see the [available phases](https://github.com/vercel/next.js/blob/5e6b008b561caf2710ab7be63320a3d549474a5b/packages/next/sh…

// @ts-check

const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')

module.exports = (phase, { defaultConfig }) => {
  if (phase === PHASE_DEVELOPMENT_SERVER) {
    return {
      /*…

TypeScript

If you are using TypeScript in your project, you can use `next.config.ts` to use TypeScript in your configuration:

The commented lines are the place where you can put the configs allowed by…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  /* config options here */
}

export default nextConfig

Unit Testing (experimental)

Starting in Next.js 15.1, the `next/experimental/testing/server` package contains utilities to help unit test `next.config.js` files.

The `unstable_getResponseFromNextConfig` function runs the…

import {
  getRedirectUrl,
  unstable_getResponseFromNextConfig,
} from 'next/experimental/testing/server'

const response = await unstable_getResponseFromNextConfig({
  url:…

Available configuration options

This page documents all the available configuration options:

- **adapterPath**: Configure a custom adapter for Next.js to hook into the build process.
- **allowedDevOrigins**: Use…


adapterPath

Summary: Documentation for the Next.js adapterPath configuration option, which allows deployment platforms or build systems to integrate with the Next.js build process via adapters.

Overview

Next.js provides a built-in adapters API. It allows deployment platforms or build systems to integrate with the Next.js build process. For a full reference implementation, see the…

Configuration

To use an adapter, specify the path to your adapter module in `adapterPath`:

Alternatively `NEXT_ADAPTER_PATH` can be set to enable zero-config usage in deployment platforms.

/** @type {import('next').NextConfig} */
const nextConfig = {
  adapterPath: require.resolve('./my-adapter.js'),
}

module.exports = nextConfig

Adapters

For full adapter implementation details, use the dedicated Adapters section:

- [Configuration](/docs/app/api-reference/adapters/configuration)
- [Creating an…

Creating an Adapter

See [Creating an Adapter](/docs/app/api-reference/adapters/creating-an-adapter).

API Reference

See [API Reference](/docs/app/api-reference/adapters/api-reference).

Testing Adapters

See [Testing Adapters](/docs/app/api-reference/adapters/testing-adapters).

Routing with `@next/routing`

See [Routing with `@next/routing`](/docs/app/api-reference/adapters/routing-with-next-routing).

Implementing PPR in an Adapter

See [Implementing PPR in an Adapter](/docs/app/api-reference/adapters/implementing-ppr-in-an-adapter).

Runtime Integration

See [Runtime Integration](/docs/app/api-reference/adapters/runtime-integration).

Invoking Entrypoints

See [Invoking Entrypoints](/docs/app/api-reference/adapters/invoking-entrypoints).

Output Types

See [Output Types](/docs/app/api-reference/adapters/output-types).

Routing Information

See [Routing Information](/docs/app/api-reference/adapters/routing-information).

Use Cases

See [Use Cases](/docs/app/api-reference/adapters/use-cases).


allowedDevOrigins

Summary: Describes the `allowedDevOrigins` config option in Next.js, which allows additional origins to request the dev server during development.

allowedDevOrigins

Next.js blocks cross-origin requests to dev-only assets and endpoints during development by default to prevent unauthorized access.

To configure a Next.js application to allow requests from origins…

module.exports = {
  allowedDevOrigins: ['local-origin.dev', '*.local-origin.dev'],
}

allowedDevOrigins

Sets additional origins that can request the dev server in development mode. Accepts exact hostnames and wildcard subdomains (e.g., 'local-origin.dev', '*.local-origin.dev').


appDir

Summary: Documents the `appDir` configuration option in next.config.js, which enables the App Router. It is a legacy API, no longer needed as of Next.js 13.4.

appDir

This is a legacy API and no longer recommended. It's still supported for backward compatibility.

Good to know: This option is no longer needed as of Next.js 13.4. The App Router is now stable.

The…


assetPrefix

Summary: Explains how to configure the `assetPrefix` option in `next.config.js` to serve static assets from a CDN.

Set up a CDN

Attention: Deploying to Vercel automatically configures a global CDN for your Next.js project. You do not need to manually setup an Asset Prefix.

Good to know: Next.js 9.5+ added support for a…

// @ts-check
import { PHASE_DEVELOPMENT_SERVER } from 'next/constants'

export default (phase) => {
  const isDev = phase === PHASE_DEVELOPMENT_SERVER
  /**
   * @type {import('next').NextConfig}…

assetPrefix

The URL prefix to use for static assets when served from a CDN.


authInterrupts

Summary: Reference for the experimental authInterrupts option in next.config.js, which enables the forbidden and unauthorized APIs in a Next.js application.

authInterrupts

This feature is currently available in the canary channel and subject to change. Try it out by [upgrading Next.js](/docs/app/getting-started/upgrading#canary-version), and share your feedback on…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    authInterrupts: true,
  },
}

export default nextConfig

experimental.authInterrupts

Enables the use of the forbidden and unauthorized APIs in your application. While these functions are experimental, this option must be enabled to use them.


basePath

Summary: Explains how to use the basePath config option in next.config.js to deploy a Next.js application under a sub-path of a domain.

basePath

To deploy a Next.js application under a sub-path of a domain you can use the `basePath` config option.

`basePath` allows you to set a path prefix for the application. For example, to use `/docs`…

module.exports = {
  basePath: '/docs',
}

Links

When linking to other pages using `next/link` and `next/router` the `basePath` will be automatically applied.

For example, using `/about` will automatically become `/docs/about` when `basePath` is…

export default function HomePage() {
  return (
    <>
      <Link href="/about">About Page</Link>
    </>
  )
}

Images

When using the [`next/image`](/docs/app/api-reference/components/image) component, you will need to add the `basePath` in front of `src`.

For example, using `/docs/me.png` will properly serve your…

import Image from 'next/image'

function Home() {
  return (
    <>

My Homepage

      <Image
        src="/docs/me.png"
        alt="Picture of the author"
        width={500}…

basePath

Path prefix for the application. Defaults to an empty string.


cacheComponents

Summary: This page documents the `cacheComponents` configuration flag in Next.js, which enables component and function-level caching using the `use cache` directive, and implements Partial Prerendering as the…

Usage

Cache Components enables component and function-level caching using the [`use cache`](/docs/app/api-reference/directives/use-cache) directive. Data fetching is dynamic by default, and you choose what…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
}

export default nextConfig

Navigation with Activity

When `cacheComponents` is enabled, Next.js uses React's [`<Activity>`](https://react.dev/reference/react/Activity) component to preserve component state during client-side navigation.

Rather than…

Version History

| Version | Change |
| --- | --- |
| 16.0.0 | `cacheComponents` introduced. This flag controls the `ppr`, `useCache`, and `dynamicIO` flags as a single, unified configuration. |

Learn more

[### Caching

Learn how to cache data and UI in Next.js](/docs/app/getting-started/caching)[### ISR with Cache Components

Learn how to prerender a subset of dynamic routes, serve App Shells for the…


next.config.js: cacheHandlers | Next.js

Summary: This page documents the `cacheHandlers` configuration in next.config.js, which lets you define custom cache storage implementations for `'use cache'` and `'use cache: remote'`. It covers handler…

cacheHandlers

The `cacheHandlers` configuration allows you to define custom cache storage implementations for [`'use cache'`](/docs/app/api-reference/directives/use-cache) and [`'use cache:…

When to use custom cache handlers

**Most applications don't need custom cache handlers.** The default in-memory cache works well in the typical use case.

Custom cache handlers are for advanced scenarios where you need to either…

Usage

To configure custom cache handlers:

- Define your cache handler in a separate file, see [examples](#examples) for implementation details.
- Reference the file path in your Next config file

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheHandlers: {
    default: require.resolve('./cache-handlers/default-handler.js'),
    remote:…

Handler types

- **`default`**: Used by the `'use cache'` directive
- **`remote`**: Used by the `'use cache: remote'` directive

If you don't configure `cacheHandlers`, Next.js uses an in-memory LRU (Least Recently…

API Reference

A cache handler must implement the [`CacheHandler`](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts) interface with the following methods:

get()

Retrieve a cache entry for the given cache key.

| Parameter | Type | Description |
| --- | --- | --- |
| `cacheKey` | `string` | The unique key for the cache entry. |
| `softTags` | `string[]` |…

get(cacheKey: string, softTags: string[]): Promise<CacheEntry | undefined>

const cacheHandler = {
  async get(cacheKey, softTags) {
    const entry = cache.get(cacheKey)
    if (!entry) return undefined

    // Check if expired
    const now = Date.now()
    if (now >…

set()

Store a cache entry for the given cache key.

| Parameter | Type | Description |
| --- | --- | --- |
| `cacheKey` | `string` | The unique key to store the entry under. |
| `pendingEntry` |…

set(cacheKey: string, pendingEntry: Promise<CacheEntry>): Promise<void>

const cacheHandler = {
  async set(cacheKey, pendingEntry) {
    // Wait for the entry to be ready
    const entry = await pendingEntry

    // Store in your cache system
    cache.set(cacheKey,…

refreshTags()

Called periodically before starting a new request to sync with external tag services.

This is useful if you're coordinating cache invalidation across multiple instances or services. For in-memory…

const cacheHandler = {
  async refreshTags() {
    // For in-memory cache, no action needed
    // For distributed cache, sync tag state from external service
  },
}

getExpiration()

Get the maximum revalidation timestamp for a set of tags.

| Parameter | Type | Description |
| --- | --- | --- |
| `tags` | `string[]` | Array of tags to check expiration for. |

Returns:

- `0` if…

const cacheHandler = {
  async getExpiration(tags) {
    // Return 0 if not tracking tag revalidation
    return 0

    // Or return the most recent revalidation timestamp
    // return…

updateTags()

Called when tags are revalidated or expired.

| Parameter | Type | Description |
| --- | --- | --- |
| `tags` | `string[]` | Array of tags to update. |
| `durations` | `{ expire?: number }` |…

updateTags(tags: string[], durations?: { expire?: number }): Promise<void>

const cacheHandler = {
  async updateTags(tags, durations) {
    // Invalidate all cache entries with matching tags
    for (const [key, entry] of cache.entries()) {
      if (entry.tags.some((tag)…

CacheEntry Type

The [`CacheEntry`](https://github.com/vercel/next.js/blob/canary/packages/next/src/server/lib/cache-handlers/types.ts) object has the following structure:

| Property | Type | Description |
| --- |…

interface CacheEntry {
  value: ReadableStream<Uint8Array>
  tags: string[]
  stale: number
  timestamp: number
  expire: number
  revalidate: number
}

Examples

Basic in-memory cache handler

Here's a minimal implementation using a `Map` for storage. This example demonstrates the core concepts, but for a production-ready implementation with LRU eviction, error handling, and tag…

const cache = new Map()
const pendingSets = new Map()

module.exports = {
  async get(cacheKey, softTags) {
    // Wait for any pending set operation to complete
    const pendingPromise =…

External storage pattern

For durable storage like Redis or a database, you'll need to serialize the cache entries. Here's a simple Redis example:

const { createClient } = require('redis')

const client = createClient({ url: process.env.REDIS_URL })
client.connect()

module.exports = {
  async get(cacheKey, softTags) {
    // Retrieve from…

Distributed Tag Coordination

When running multiple Next.js instances, tag invalidation must be coordinated across instances. The default in-memory handler only tracks tags locally, so calling `revalidateTag()` on one instance…

const { createClient } = require('redis')

const client = createClient({ url: process.env.REDIS_URL })
client.connect()

// Local cache of tag timestamps, synced via refreshTags
const…

Soft Tags

Soft tags are implicit tags that Next.js automatically generates based on the route path. For example, the route `/blog/hello` generates soft tags for `/`, `/blog`, `/blog/hello`, and their…

Handling Streams

The `CacheEntry.value` is a [`ReadableStream<Uint8Array>`](https://developer.mozilla.org/docs/Web/API/ReadableStream). When implementing a cache handler that stores entries externally, keep in…

Error Handling

Cache operations should be implemented defensively:

- **`set()` failure**: the response is still served to the user because `set()` is called asynchronously after the response stream is already…

Platform Support

| Deployment Option | Supported |
| --- | --- |
| [Node.js server](/docs/app/getting-started/deploying#nodejs-server) | Yes |
| [Docker container](/docs/app/getting-started/deploying#docker) | Yes…

Version History

| Version | Changes |
| --- | --- |
| `v16.0.0` | `cacheHandlers` introduced. |

Related

View related API references.

- [use cache](/docs/app/api-reference/directives/use-cache) — Learn how to use the "use cache" directive to cache data in your Next.js application.
- [use cache:…

cacheKey

The unique key for the cache entry.

softTags

Implicit tags derived from the route path. See Soft Tags for how to use them.

pendingEntry

A promise that resolves to the cache entry.

tags

Array of tags to check expiration for.

Array of tags to update.

durations

Optional expiration duration in seconds.

value

The cached data as a stream.

tags

Cache tags (excluding soft tags).

stale

Duration in seconds for client-side staleness.

timestamp

When the entry was created (timestamp in milliseconds).

expire

How long the entry is allowed to be used (in seconds).

revalidate

How long until the entry should be revalidated (in seconds).


next.config.js: cacheLife | Next.js

Summary: Reference for the cacheLife option in next.config.js, which lets you define custom cache profiles for use with the cacheLife function and the use cache directive.

cacheLife

The `cacheLife` option allows you to define **custom cache profiles** when using the [`cacheLife`](/docs/app/api-reference/functions/cacheLife) function inside components or functions, and within the…

Usage

To define a profile, enable the [`cacheComponents` flag](/docs/app/api-reference/config/next-config-js/cacheComponents) and add the cache profile in the `cacheLife` object in the `next.config.js`…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
  cacheLife: {
    blog: {
      stale: 3600, // 1 hour
      revalidate: 900, // 15 minutes…

import { cacheLife } from 'next/cache'

export async function getCachedData() {
  'use cache'
  cacheLife('blog')
  const data = await fetch('/api/data')
  return data
}

Reference

The configuration object has key values with the following format:

| **Property** | **Value** | **Description** | **Requirement** |
| --- | --- | --- | --- |
| `stale` | `number` | Duration the…

Related

View related API references.

- [use cache](/docs/app/api-reference/directives/use-cache) — Learn how to use the "use cache" directive to cache data in your Next.js application.
-…

stale

Duration the client should cache a value without checking the server.

revalidate

Frequency at which the cache should refresh on the server; stale values may be served while revalidating.

expire

Maximum duration for which a value can remain stale before switching to dynamic. Must be longer than `revalidate`.


compress

Summary: This page describes the `compress` option in `next.config.js`, which controls gzip compression for rendered content and static files when using `next start` or a custom server.

compress

By default, Next.js uses `gzip` to compress rendered content and static files when using `next start` or a custom server. This is an optimization for applications that do not have compression…

Disabling compression

To disable **compression**, set the `compress` config option to `false`:

We **do not recommend disabling compression** unless you have compression configured on your server, as compression reduces…

compress

Enables or disables gzip compression for rendered content and static files when using `next start` or a custom server. Defaults to `true` unless compression is already configured via a custom server.


crossOrigin

Summary: Use the `crossOrigin` option to add a `crossOrigin` attribute in all `<script>` tags generated by the `next/script` component, and define how cross-origin requests should be handled.

crossOrigin

Use the `crossOrigin` option to add a [`crossOrigin` attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin) in all `<script>` tags generated by the…

module.exports = {
  crossOrigin: 'anonymous',
}

Options

- `'anonymous'`: Adds [`crossOrigin="anonymous"`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/crossorigin#anonymous) attribute.

- `'use-credentials'`: Adds…

crossOrigin

Adds a crossOrigin attribute to all script tags generated by next/script. Can be 'anonymous' or 'use-credentials'.


next.config.js: cssChunking

Summary: This page documents the experimental `cssChunking` option in Next.js configuration, which controls how CSS files are split and re-ordered into chunks to improve performance. It covers the available…

cssChunking

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on GitHub.

CSS Chunking is a strategy used to improve the…

import type { NextConfig } from 'next'

const nextConfig = {
  experimental: {
    cssChunking: true, // default
  },
} satisfies NextConfig

export default nextConfig

Options

- **`true` (default)** (**webpack and Turbopack**): Next.js will try to merge CSS files whenever possible, determining explicit and implicit dependencies between files from import order to reduce the…

Choosing a strategy

For most applications, the default (`true`) is the right choice in either bundler: it merges CSS to make fewer requests. Reach for another strategy only for a specific reason.

In Turbopack, that…

Debugging what a route actually uses

While some unused CSS is acceptable, and most apps do not need to change anything, it is worth keeping render-blocking CSS in check. Lighthouse flags this as a **Reduce unused CSS** opportunity with…

Balancing requests and grouping

The `graph` strategy groups CSS into shared chunks to cut requests. Turn it on with the string form, which uses the default tuning:

import type { NextConfig } from 'next'

const nextConfig = {
  experimental: {
    cssChunking: 'graph',
  },
} satisfies NextConfig

export default nextConfig

Balancing requests and grouping (continued)

To shift that balance, pass an object instead. Both `requestCost` and `weightDistribution` are optional, so include only the one you want to change:

import type { NextConfig } from 'next'

const nextConfig = {
  experimental: {
    cssChunking: {
      type: 'graph',
      requestCost: 100000,
      weightDistribution: 0.1,
    },
  },
}…

Balancing requests and grouping (options)

- **`requestCost`** (default `20000`): the estimated cost, in bytes, of each additional CSS request. Larger values bias toward fewer, larger shared chunks, and fewer requests overall.

-…

How `graph` decides what to merge

Merging CSS into shared chunks is what the default (`true`) already does; `graph` just lets you control where it draws the line between merging and splitting.

Take two routes that share a…

Graph algorithm overview

At a high level, the algorithm works with individual CSS files. It starts from the ordered list of CSS each route imports:

```
/dashboard  → [reset.css, theme.css, layout.css,…


next.config.js: deploymentId

Summary: Documentation for the Next.js `deploymentId` configuration option, which sets a deployment identifier for version skew protection and cache busting during rolling deployments. Covers configuration,…

deploymentId

The `deploymentId` option allows you to set an identifier for your deployment. This identifier is used for [version skew](https://nextjs.org/docs/app/guides/self-hosting#version-skew) protection and…

module.exports = {
  deploymentId: 'my-deployment-id',
}

How it works

When a `deploymentId` is configured, Next.js:

- Appends `?dpl=<deploymentId>` to static asset URLs (JavaScript, CSS, images)
- Adds an `x-deployment-id` header to client-side navigation requests
-…

Use cases

Rolling deployments

During a rolling deployment, some server instances may be running the new version while others are still running the old version. Without a deployment ID, users might receive a mix of old and new…

Multi-server environments

When running multiple instances of your Next.js application behind a load balancer, all instances for the same deployment should use the same `deploymentId`.

module.exports = {
  deploymentId: process.env.DEPLOYMENT_VERSION || process.env.GIT_SHA,
}

Version History

| Version | Changes |
| --- | --- |
| `v14.1.4` | `deploymentId` stabilized as top-level config option. |
| `v13.4.10` | `experimental.deploymentId` introduced. |

Related

- [Self-Hosting - Version Skew](https://nextjs.org/docs/app/guides/self-hosting#version-skew)
- [generateBuildId](https://nextjs.org/docs/app/api-reference/config/next-config-js/generateBuildId)


devIndicators

Summary: Configuration for the on-screen development indicator in Next.js, allowing you to set its position or hide it entirely.

devIndicators

`devIndicators` allows you to configure the on-screen indicator that gives context about the current route you're viewing during development. Open `next.config.ts` and set `position` to choose where…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  devIndicators: {
    position: 'bottom-right', // 'bottom-left' | 'bottom-right' | 'top-left' | 'top-right'
  },
}

export…

const nextConfig: NextConfig = {
  devIndicators: false,
}

export default nextConfig

Troubleshooting

Indicator not marking a route as static

If you expect a route to be static and the indicator has marked it as dynamic, it's likely the route has opted out of prerendering. You can confirm if a route is…

Route (app)
┌ ○ /_not-found
└ ƒ /products/[id]

○  (Static)   prerendered as static content
ƒ  (Dynamic)  server-rendered on demand

Version History

| Version | Changes |
| --- | --- |
| `v16.0.0` | `appIsrStatus`, `buildActivity`, and `buildActivityPosition` options have been removed. |
| `v15.2.0` | Improved on-screen indicator with new…

devIndicators

Configuration for the on-screen development indicator. Set to `false` to hide it entirely.

position

Position of the indicator on the screen.


distDir

Summary: Documentation for the distDir configuration option in next.config.js, which lets you specify a custom build directory instead of the default .next folder.

distDir

You can specify a name to use for a custom build directory to use instead of `.next`.

Open `next.config.js` and add the `distDir` config:

Now if you run `next build` Next.js will use `build`…

module.exports = {
  distDir: 'build',
}


env

Summary: Describes the legacy `env` config option in next.config.js for adding environment variables to the JavaScript bundle, noting it's no longer recommended.

env

This is a legacy API and no longer recommended. It's still supported for backward compatibility.

> Since the release of [Next.js 9.4](https://nextjs.org/blog/next-9-4) we now have a more intuitive…

module.exports = {
  env: {
    customKey: 'my-value',
  },
}

function Page() {
  return
The value of customKey is: {process.env.customKey}

}

export default Page

return
The value of customKey is: {'my-value'}


expireTime

Summary: Describes the `expireTime` configuration option in Next.js, which sets a custom stale-while-revalidate expire time for CDNs in the Cache-Control header for ISR pages.

expireTime

You can specify a custom `stale-while-revalidate` expire time for CDNs to consume in the `Cache-Control` header for ISR enabled pages.

Open `next.config.js` and add the `expireTime` config:

Now…

module.exports = {
  // one hour in seconds
  expireTime: 3600,
}

expireTime

Custom stale-while-revalidate expire time in seconds for CDNs to consume in the Cache-Control header for ISR enabled pages.


next.config.js: exportPathMap | Next.js

Summary: This page documents exportPathMap, a legacy Next.js configuration option for specifying a mapping of request paths to page destinations during static export.

exportPathMap

This is a legacy API and no longer recommended. It's still supported for backward compatibility.

> This feature is exclusive to `next export` and currently **deprecated** in favor of…

module.exports = {
  exportPathMap: async function (
    defaultPathMap,
    { dev, dir, outDir, distDir, buildId }
  ) {
    return {
      '/': { page: '/' },
      '/about': { page: '/about' },…

Adding a trailing slash

It is possible to configure Next.js to export pages as `index.html` files and require trailing slashes, `/about` becomes `/about/index.html` and is routable via `/about/`. This was the default…

module.exports = {
  trailingSlash: true,
}

Customizing the output directory

[`next export`](/docs/app/guides/static-exports) will use `out` as the default output directory, you can customize this using the `-o` argument, like so:

```terminal
next export -o outdir
```

>…


generateBuildId

Summary: Explains how to use the generateBuildId option in next.config.js to generate a consistent build ID for your Next.js application.

generateBuildId

Next.js generates an ID during `next build` to identify which version of your application is being served. The same build should be used and boot up multiple containers.

If you are rebuilding for…

module.exports = {
  generateBuildId: async () => {
    // This could be anything, using the latest git hash
    return process.env.GIT_HASH
  },
}


generateEtags

Summary: This page describes the `generateEtags` configuration option in `next.config.js`, which controls whether Next.js generates ETags for every page. It shows how to disable ETag generation for HTML pages.

generateEtags

Next.js will generate [etags](https://en.wikipedia.org/wiki/HTTP_ETag) for every page by default. You may want to disable etag generation for HTML pages depending on your cache strategy.

Open…

module.exports = {
  generateEtags: false,
}

generateEtags

When set to false, disables ETag generation for HTML pages. Defaults to true.


next.config.js: headers

Summary: This page explains how to set custom HTTP headers on responses in Next.js using the `headers` key in `next.config.js`, covering path matching, regex, header/cookie/query matching, basePath/i18n…

headers

Headers allow you to set custom HTTP headers on the response to an incoming request on a given path.

To set custom HTTP headers you can use the `headers` key in `next.config.js`:

`headers` can be…

module.exports = {
  headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'my custom header value',…

Header Overriding Behavior

If two headers match the same path and set the same header key, the last header key will override the first. Using the below headers, the path `/hello` will result in the header `x-hello` being…

module.exports = {
  headers() {
    return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'x-hello',
            value: 'there',
          },
        ],…

Path Matching

Path matches are allowed, for example `/blog/:slug` will match `/blog/first-post` (no nested paths):

The pattern `/blog/:slug` matches `/blog/first-post` and `/blog/post-1` but not a nested path…

module.exports = {
  headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // Matched parameters can be…

Wildcard Path Matching

To match a wildcard path you can use `*` after a parameter, for example `/blog/:slug*` will match `/blog/a/b/c/d/hello-world`:

module.exports = {
  headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // Matched parameters can…

Regex Path Matching

To match a regex path you can wrap the regex in parenthesis after a parameter, for example `/blog/:slug(\d{1,})` will match `/blog/123` but not `/blog/abc`:

The following characters `(`, `)`, `{`,…

module.exports = {
  headers() {
    return [
      {
        source: '/blog/:post(\\d{1,})',
        headers: [
          {
            key: 'x-post',
            value: ':post',
          },…

module.exports = {
  headers() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        headers: […

Header, Cookie, and Query Matching

To only apply a header when header, cookie, or query values also match the `has` field or don't match the `missing` field can be used. Both the `source` and all `has` items must match and all…

module.exports = {
  headers() {
    return [
      // if the header `x-add-header` is present,
      // the `x-another-header` header will be applied
      {
        source: '/:path*',
        has:…

Headers with basePath support

When leveraging [`basePath` support](/docs/app/api-reference/config/next-config-js/basePath) with headers each `source` is automatically prefixed with the `basePath` unless you add `basePath: false`…

module.exports = {
  basePath: '/docs',

  headers() {
    return [
      {
        source: '/with-basePath', // becomes /docs/with-basePath
        headers: [
          {
            key:…

Headers with i18n support

When leveraging [`i18n` support](/docs/app/guides/internationalization) with headers each `source` is automatically prefixed to handle the configured `locales` unless you add `locale: false` to the…

module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },

  headers() {
    return [
      {
        source: '/with-locale', // automatically handles all locales…

Cache-Control

Next.js sets the `Cache-Control` header of `public, max-age=31536000, immutable` for truly immutable assets. It cannot be overridden. These immutable files contain a SHA-hash in the file name, so…

Options

CORS

[Cross-Origin Resource Sharing (CORS)](https://developer.mozilla.org/docs/Web/HTTP/CORS) is a security feature that allows you to control which sites can access your resources. You can set the…

headers() {
    return [
      {
        source: "/api/:path*",
        headers: [
          {
            key: "Access-Control-Allow-Origin",
            value: "*", // Set your origin
          },…

X-DNS-Prefetch-Control

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-DNS-Prefetch-Control) controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links,…

{
  key: 'X-DNS-Prefetch-Control',
  value: 'on'
}

Strict-Transport-Security

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Strict-Transport-Security) informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration…

{
  key: 'Strict-Transport-Security',
  value: 'max-age=63072000; includeSubDomains; preload'
}

X-Frame-Options

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Frame-Options) indicates whether the site should be allowed to be displayed within an `iframe`. This can prevent against…

{
  key: 'X-Frame-Options',
  value: 'SAMEORIGIN'
}

Permissions-Policy

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Permissions-Policy) allows you to control which features and APIs can be used in the browser. It was previously named…

{
  key: 'Permissions-Policy',
  value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}

X-Content-Type-Options

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/X-Content-Type-Options) prevents the browser from attempting to guess the type of content if the `Content-Type` header is not…

{
  key: 'X-Content-Type-Options',
  value: 'nosniff'
}

Referrer-Policy

[This header](https://developer.mozilla.org/docs/Web/HTTP/Headers/Referrer-Policy) controls how much information the browser includes when navigating from the current website (origin) to another.

{
  key: 'Referrer-Policy',
  value: 'origin-when-cross-origin'
}

Content-Security-Policy

Learn more about adding a [Content Security Policy](/docs/app/guides/content-security-policy) to your application.

Version History

| Version | Changes |
| --- | --- |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Headers added. |

source

The incoming request path pattern.

headers

An array of response header objects, with `key` and `value` properties.

basePath

If false the basePath won't be included when matching, can be used for external rewrites only.

locale

Whether the locale should not be included when matching.

has

Array<{ type: 'header' | 'cookie' | 'host' | 'query', key: string, value?: string | undefined }>

An array of has objects with the `type`, `key` and `value` properties. All must match for the header to be applied.

missing

An array of missing objects with the `type`, `key` and `value` properties. All must not match for the header to be applied.


htmlLimitedBots

Summary: The `htmlLimitedBots` config allows you to specify a list of user agents that should receive blocking metadata instead of streaming metadata in Next.js.

htmlLimitedBots

The `htmlLimitedBots` config allows you to specify a list of user agents that should receive blocking metadata instead of [streaming…

import type { NextConfig } from 'next'

const config: NextConfig = {
  htmlLimitedBots: /MySpecialBot|MyAnotherSpecialBot|SimpleCrawler/,
}

export default config

Default list

Next.js includes a default list of HTML limited bots, including:

- Google crawlers (e.g. Mediapartners-Google, AdsBot-Google, Google-PageRenderer)
- Bingbot
- Twitterbot
- Slackbot

See the full…

Disabling

To fully disable streaming metadata:

import type { NextConfig } from 'next'

const config: NextConfig = {
  htmlLimitedBots: /.*/,
}

export default config

Version History

| Version | Changes |
| --- | --- |
| 15.2.0 | `htmlLimitedBots` option introduced. |


httpAgentOptions

Summary: Explains the httpAgentOptions configuration in next.config.js, which controls HTTP Keep-Alive behavior for server-side fetch() calls. Shows how to disable Keep-Alive by setting keepAlive to false.

httpAgentOptions

In Node.js versions prior to 18, Next.js automatically polyfills `fetch()` with [undici](/docs/architecture/supported-browsers#polyfills) and enables [HTTP…

module.exports = {
  httpAgentOptions: {
    keepAlive: false,
  },
}

keepAlive

When set to false, disables HTTP Keep-Alive for all fetch() calls on the server-side.


next.config.js: images

Summary: This page explains how to configure the `images` option in `next.config.js` to use a custom image loader for cloud providers, including example loader implementations for various providers.

images

If you want to use a cloud provider to optimize images instead of using the Next.js built-in Image Optimization API, you can configure `next.config.js` with the following:

This `loaderFile` must…

module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my/image/loader.js',
  },
}

'use client'

export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

Example Loader Configuration

Akamai

// Docs: https://techdocs.akamai.com/ivm/reference/test-images-on-demand
export default function akamaiLoader({ src, width, quality }) {
  return `https://example.com/${src}?imwidth=${width}`
}

AWS CloudFront

// Docs: https://aws.amazon.com/developer/application-security-performance/articles/image-optimization
export default function cloudfrontLoader({ src, width, quality }) {
  const url = new…

Cloudinary

// Demo: https://res.cloudinary.com/demo/image/upload/w_300,c_limit,q_auto/turtles.jpg
export default function cloudinaryLoader({ src, width, quality }) {
  const params = ['f_auto', 'c_limit',…

Cloudflare

// Docs: https://developers.cloudflare.com/images/transform-images
export default function cloudflareLoader({ src, width, quality }) {
  const params = [`width=${width}`, `quality=${quality || 75}`,…

Contentful

// Docs: https://www.contentful.com/developers/docs/references/images-api/
export default function contentfulLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)…

Fastly

// Docs: https://developer.fastly.com/reference/io/
export default function fastlyLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)
  url.searchParams.set('auto',…

Gumlet

// Docs: https://docs.gumlet.com/reference/image-transform-size
export default function gumletLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)…

ImageEngine

// Docs: https://support.imageengine.io/hc/en-us/articles/360058880672-Directives
export default function imageengineLoader({ src, width, quality }) {
  const compression = 100 - (quality || 50)…

Imgix

// Demo: https://static.imgix.net/daisy.png?format=auto&fit=max&w=300
export default function imgixLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)
  const params…

PixelBin

// Doc (Resize): https://www.pixelbin.io/docs/transformations/basic/resize/#width-w
// Doc (Optimise): https://www.pixelbin.io/docs/optimizations/quality/#image-quality-when-delivering
// Doc (Auto…

Sanity

// Docs: https://www.sanity.io/docs/image-urls
export default function sanityLoader({ src, width, quality }) {
  const prj = 'zp7mbokg'
  const dataset = 'production'
  const url = new…

Sirv

// Docs: https://sirv.com/help/articles/dynamic-imaging/
export default function sirvLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)
  const params =…

Supabase

// Docs: https://supabase.com/docs/guides/storage/image-transformations#nextjs-loader
export default function supabaseLoader({ src, width, quality }) {
  const url = new…

Thumbor

// Docs: https://thumbor.readthedocs.io/en/latest/
export default function thumborLoader({ src, width, quality }) {
  const params = [`${width}x0`, `filters:quality(${quality || 75})`]
  return…

ImageKit.io

// Docs: https://imagekit.io/docs/image-transformation
export default function imageKitLoader({ src, width, quality }) {
  const params = [`w-${width}`, `q-${quality || 80}`]
  return…

Nitrogen AIO

// Docs: https://docs.n7.io/aio/intergrations/
export default function aioLoader({ src, width, quality }) {
  const url = new URL(src, window.location.href)
  const params = url.searchParams
  const…


Custom Next.js Cache Handler

Summary: Explains how to configure a custom cache handler in next.config.js to persist cached pages and data to durable storage or share cache across instances, including method signatures and image…

Custom Next.js Cache Handler

You can configure the Next.js cache location if you want to persist cached pages and data to durable storage, or share the cache across multiple containers or instances of your Next.js…

module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  cacheMaxMemorySize: 0, // disable default in-memory caching
}

API Reference

The cache handler can implement the following methods: `get`, `set`, `revalidateTag`, and `resetRequestCache`.

get()

The `ctx` parameter contains a `kind` property that indicates the type of cache entry being retrieved. Possible values include `'APP_PAGE'`, `'APP_ROUTE'`, `'PAGES'`, `'FETCH'`, and…

set()

The `data` object contains a `kind` property that indicates the type of cache entry. For image optimization, `kind` will be `'IMAGE'` and the data will include properties like `buffer`, `etag`,…

revalidateTag()

Returns `Promise<void>`. Learn more about [revalidating data](/docs/app/guides/incremental-static-regeneration) or the [`revalidateTag()`](/docs/app/api-reference/functions/revalidateTag)…

resetRequestCache()

This method resets the temporary in-memory cache for a single request before the next request.

Returns `void`.

**Good to know:**

- `revalidatePath` is a convenience layer on top of cache tags.…

Image Optimization Caching

The `cacheHandler` can also be used for caching optimized images from `next/image`. To enable this, set `images.customCacheHandler` to `true` in your `next.config.js`:

> **Good to know** : This…

module.exports = {
  cacheHandler: require.resolve('./cache-handler.js'),
  images: {
    customCacheHandler: true,
  },
}

Platform Support

| Deployment Option | Supported |
| --- | --- |
| [Node.js server](/docs/app/getting-started/deploying#nodejs-server) | Yes |
| [Docker container](/docs/app/getting-started/deploying#docker) | Yes…

Version History

| Version | Changes |
| --- | --- |
| `v16.2.0` | `cacheHandler` support for image optimization caching. |
| `v14.1.0` | Renamed to `cacheHandler` and became stable. |
| `v13.4.0` |…

key

The key to the cached value (used in get).

ctx

Context including the cache entry kind (used in get).

key

The key to store the data under (used in set).

data

The data to be cached (used in set).

ctx

The cache tags provided (used in set).

tag

The cache tags to revalidate (used in revalidateTag).


next.config.js: inlineCss | Next.js

Summary: Experimental Next.js configuration option that inlines CSS into the <head> by generating <style> tags instead of <link> tags, including trade-offs, benefits, and known limitations.

inlineCss

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on [GitHub](https://github.com/vercel/next.js/issues).

Usage

Experimental support for inlining CSS in the ``. When this flag is enabled, all places where we normally generate a `<link>` tag will instead have a generated `<style>` tag.

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    inlineCss: true,
  },
}

export default nextConfig

Trade-Offs

- **Enable** if you use atomic CSS (like Tailwind) and want to optimize first-load performance for new visitors
- **Skip** if returning visitors are common and you want them to benefit from cached…

When Inline CSS Helps

Normally, the browser must download HTML, parse it, discover CSS `<link>` tags, then request stylesheets before it can render. Inlining [eliminates this request…

When External CSS is Better

Inlined styles cannot be cached separately from HTML. Every page load re-downloads the same CSS.

This trade-off matters most with:

- **Returning visitors**: Users who visit your site repeatedly…

Good to know

This feature is currently experimental and has some known limitations:

- CSS inlining is applied globally and cannot be configured on a per-page basis
- Styles are duplicated during initial page…


next.config.js: instrumentationClientInject | Next.js

Summary: This page documents the `instrumentationClientInject` option in `next.config.js`, which allows plugins to inject client-side instrumentation modules that run before the user's…

instrumentationClientInject

`instrumentationClientInject` is a list of modules that are imported on the client for their side effects before the user's…

module.exports = function withMyInstrumentation(nextConfig = {}) {
  return {
    ...nextConfig,
    instrumentationClientInject: [
      ...(nextConfig.instrumentationClientInject ?? []),…

/** @type {import('next').NextConfig} */
module.exports = {
  instrumentationClientInject: [
    'my-analytics-package',
    './lib/sentry-client.js',
  ],
}

Execution order

Modules run on the client in this order:

- Each entry in `instrumentationClientInject`, in array order.
- The project's `instrumentation-client.{js,ts}` file, if present.
- React hydration.

Router navigation hook

Each injected module may optionally export an `onRouterTransitionStart` function with the same signature as the one documented for the [`instrumentation-client` file…

// Side-effectful setup runs at load time.
setupSentry()

export function onRouterTransitionStart(url, navigationType) {
  recordNavigationBreadcrumb(url, navigationType)
}

Version history

| Version | Changes |
| --- | --- |
| `v16.3.0` | `instrumentationClientInject` introduced |


next.config.js: logging

Summary: Configuration options for logging in Next.js, including fetch logging, server functions, incoming requests, browser console logs, and disabling logging.

Options

Fetching

You can configure the logging level and whether the full URL is logged to the console when running Next.js in development mode.

Any `fetch` requests that are restored from the [Server Components HMR…

module.exports = {
  logging: {
    fetches: {
      fullUrl: true,
    },
  },
}

module.exports = {
  logging: {
    fetches: {
      hmrRefreshes: true,
    },
  },
}

Server Functions

[Server Function](https://react.dev/reference/rsc/server-functions) invocations are logged by default during development. You can disable this by setting `logging.serverFunctions` to `false`.

When…

module.exports = {
  logging: {
    serverFunctions: false,
  },
}

POST /
  └─ ƒ myAction(arg1, arg2) in 5ms app/actions.ts

Incoming Requests

By default all the incoming requests will be logged in the console during development. You can use the `incomingRequests` option to decide which requests to ignore.
Since this is only logged in…

module.exports = {
  logging: {
    incomingRequests: {
      ignore: [/\api\/v1\/health/],
    },
  },
}

module.exports = {
  logging: {
    incomingRequests: false,
  },
}

Browser Console Logs

You can forward browser console logs (such as `console.log`, `console.warn`, `console.error`) to the terminal during development. This is useful for debugging client-side code without needing to…

module.exports = {
  logging: {
    browserToTerminal: true,
  },
}

Source Location

When enabled, browser logs include source location information (file path and line number) by default. For example:

'use client'

export default function Home() {
  return (
    <button
      type="button"
      onClick={() => {
        console.log('Hello World')
      }}
    >
      Click me
    </button>
  )
}

[browser] Hello World (app/page.tsx:8:17)

Disabling Logging

In addition, you can disable the development logging by setting `logging` to `false`.

Version History

| Version | Changes |
| --- | --- |
| `v16.2.0` | `browserToTerminal` added (moved from `experimental.browserDebugInfoInTerminal`) |
| `v15.4.0` | `experimental.browserDebugInfoInTerminal` introduced…

logging

Main logging configuration. Can be set to `false` to disable all development logging.

logging.fetches.fullUrl

Whether to log the full URL for fetch requests in development.

logging.fetches.hmrRefreshes

Whether to log fetch requests restored from the Server Components HMR cache.

logging.serverFunctions

Whether to log Server Function invocations in development. Defaults to `true`.

logging.incomingRequests

Configuration for logging incoming requests. Can be an object with an `ignore` array or `false` to disable.

logging.incomingRequests.ignore

Array of regular expressions to match requests to ignore from logging.

logging.browserToTerminal

Forward browser console logs to terminal. Can be `true`, `false`, `'warn'`, or `'error'`. Defaults to `'warn'`.


mdxRs

Summary: Explains the experimental `mdxRs` config option in Next.js, which enables the Rust compiler for MDX files when used with `@next/mdx`.

mdxRs

For experimental use with `@next/mdx`. Compiles MDX files using the new Rust compiler.

This feature is currently experimental and subject to change, it's not recommended for production. Try it out…

const withMDX = require('@next/mdx')()

/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['ts', 'tsx', 'mdx'],
  experimental: {
    mdxRs: true,
  },
}…


next.config.js: onDemandEntries | Next.js

Summary: Explains the onDemandEntries configuration option in next.config.js, which controls how the development server keeps built pages in memory.

onDemandEntries

Next.js exposes some options that give you some control over how the server will dispose or keep in memory built pages in development.

To change the defaults, open `next.config.js` and add the…

module.exports = {
  onDemandEntries: {
    // period (in ms) where the server will keep pages in the buffer
    maxInactiveAge: 25 * 1000,
    // number of pages that should be kept simultaneously…

maxInactiveAge

Period (in ms) where the server will keep pages in the buffer.

pagesBufferLength

Number of pages that should be kept simultaneously without being disposed.


optimizePackageImports

Summary: Describes the experimental `optimizePackageImports` option in next.config.js, which optimizes package imports by only loading the modules actually used, and lists the libraries optimized by default.

optimizePackageImports

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on GitHub.

Some packages can export hundreds or thousands of…

module.exports = {
  experimental: {
    optimizePackageImports: ['package-name'],
  },
}

experimental.optimizePackageImports

An array of package names to optimize. Adding a package to this option will only load the modules you are actually using, while still giving you the convenience of writing import statements with many…


next.config.js: output | Next.js

Summary: This page documents the `output` option in `next.config.js`, which enables Next.js to trace page dependencies during builds and optionally create a standalone folder containing only the necessary…

output

During a build, Next.js will automatically trace each page and its dependencies to determine all of the files that are needed for deploying a production version of your application.

This feature…

How it Works

During `next build`, Next.js will use [`@vercel/nft`](https://github.com/vercel/nft) to statically analyze `import`, `require`, and `fs` usage to determine all files that a page might load.

Next.js'…

Automatically Copying Traced Files

Next.js can automatically create a `standalone` folder that copies only the necessary files for a production deployment including select files in `node_modules`.

To leverage this automatic copying…

module.exports = {
  output: 'standalone',
}

cp -r public .next/standalone/ && cp -r .next/static .next/standalone/.next/

Caveats

While tracing in monorepo setups, the project directory is used for tracing by default. For `next build packages/web-app`, `packages/web-app` would be the tracing root and any files outside of that…

const path = require('path')

module.exports = {
  // this includes files from the monorepo base two directories up
  outputFileTracingRoot: path.join(__dirname, '../../'),
}

module.exports = {
  outputFileTracingExcludes: {
    '/api/hello': ['./un-necessary-folder/**/*'],
  },
  outputFileTracingIncludes: {
    '/api/another': ['./necessary-folder/**/*'],…

module.exports = {
  outputFileTracingIncludes: {
    '/products/*': ['src/lib/payments/**/*'],
    '/*': ['src/config/runtime/**/*.json'],
  },
  outputFileTracingExcludes: {
    '/api/*':…

module.exports = {
  outputFileTracingIncludes: {
    '/*': ['src/i18n/locales/**/*.json'],
  },
}

const path = require('path')

module.exports = {
  // Trace from the monorepo root
  outputFileTracingRoot: path.join(__dirname, '../../'),
  outputFileTracingIncludes: {
    '/route1':…

module.exports = {
  outputFileTracingIncludes: {
    '/*': ['node_modules/sharp/**/*', 'node_modules/aws-crt/dist/bin/**/*'],
  },
}

output

Set to 'standalone' to create a standalone folder at `.next/standalone` containing only the necessary files for a production deployment, including select files in `node_modules`.

outputFileTracingRoot

Sets the root directory used for output file tracing. Useful in monorepo setups to include files outside the project directory.

outputFileTracingExcludes

An object whose keys are route globs (matched with picomatch against the route path) and whose values are glob patterns resolved from the project root that specify files to exclude from the trace.

outputFileTracingIncludes

An object whose keys are route globs (matched with picomatch against the route path) and whose values are glob patterns resolved from the project root that specify files to include in the trace.


outputHashSalt

Summary: This page documents the `outputHashSalt` option in Next.js configuration, which adds a salt string to output filenames to invalidate cached assets across deployments.

Overview

`outputHashSalt` is an option that incorporates a configurable salt string into every content-addressed output filename (chunks, assets). Changing this value forces all output hashes to change, which…

Configuration

To configure the output hash salt, set `outputHashSalt` in `next.config.js`:

/** @type {import('next').NextConfig} */
const nextConfig = {
  outputHashSalt: 'my-deployment-salt',
}

module.exports = nextConfig

Bundler Support

This works with both Webpack and Turbopack bundlers.

Environment Variable

The `NEXT_HASH_SALT` environment variable can also be used for the same purpose. When both are set, the values are **concatenated** (`outputHashSalt + NEXT_HASH_SALT`) to form the effective salt.…

Version History


next.config.js: pageExtensions | Next.js

Summary: Reference for the pageExtensions option in next.config.js, which customizes which file extensions Next.js treats as pages—for example, to support Markdown and MDX.

pageExtensions

By default, Next.js accepts files with the following extensions: `.tsx`, `.ts`, `.jsx`, `.js`. This can be modified to allow other extensions like markdown (`.md`, `.mdx`).

const withMDX = require('@next/mdx')()

/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['js', 'jsx', 'ts', 'tsx', 'md', 'mdx'],
}

module.exports =…

pageExtensions

Modifies the file extensions that Next.js accepts for pages. Defaults to .tsx, .ts, .jsx, .js; can include markdown extensions like .md and .mdx.


partialPrefetching

Summary: Configuration option for Next.js that enables Partial Prefetching at the app level, allowing the framework to prefetch reusable App Shells per route instead of per link.

Usage

`partialPrefetching` requires [`cacheComponents`](/docs/app/api-reference/config/next-config-js/cacheComponents). Without it, `next dev` and `next build` throw at config validation.

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  cacheComponents: true,
  partialPrefetching: true,
}

export default nextConfig

Reference

| Value | Description |
| --- | --- |
| `true` | Enables Partial Prefetching across the app. |
| `false` | Default. No change to prefetch behavior. |

How prefetches resolve

Before Partial Prefetching, Next.js prefetched per visible link: a page with N links to N routes produced ~N route prefetches as those links entered the viewport.

With `partialPrefetching: true`,…

Per-segment overrides

A segment that exports an explicit [`prefetch`](/docs/app/api-reference/file-conventions/route-segment-config/prefetch) value overrides the app-level default for that route.

Version History

| Version | Change |
| --- | --- |
| 16.3.0 | `partialPrefetching` introduced. Requires `cacheComponents` to be enabled. |

Related

View related API references and guides.
- [cacheComponents - Learn how to enable the cacheComponents flag in Next.js.](/docs/app/api-reference/config/next-config-js/cacheComponents)
- [prefetch - API…

partialPrefetching

Enables Partial Prefetching at the app level. Requires `cacheComponents` to be enabled.


next.config.js: poweredByHeader

Summary: Explains how to disable the `x-powered-by` header in Next.js by setting `poweredByHeader: false` in `next.config.js`.

poweredByHeader

By default Next.js will add the `x-powered-by` header. To opt-out of it, open `next.config.js` and disable the `poweredByHeader` config:

module.exports = {
  poweredByHeader: false,
}


prefetchInlining

Summary: Describe the experimental `prefetchInlining` configuration option in Next.js, which controls whether App Router prefetch responses are bundled into a single response, and how to disable or customize…

prefetchInlining

When the App Router prefetches a route, it can bundle small segment responses into a single response instead of requesting each one separately. This reduces the number of prefetch requests at the…

Usage

To turn off prefetch inlining, set `experimental.prefetchInlining` to `false`:

To override the thresholds instead of disabling inlining, pass an object. Any value you omit keeps its default:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    prefetchInlining: false,
  },
}

export default nextConfig

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    prefetchInlining: {
      maxSize: 2048,
      maxBundleSize: 10240,
    },
  },
}

export default…

Reference

| Value | Description |
| --- | --- |
| `true` | Inlines prefetch responses with the default thresholds. This is the default. |
| `false` | Disables prefetch inlining. Each segment is prefetched as…

Version History

| Version | Change |
| --- | --- |
| 16.3.0 | `experimental.prefetchInlining` enabled by default. |
| 16.2.0 | `experimental.prefetchInlining` added. |

Related

View related API references and guides.

[Link Component](/docs/app/api-reference/components/link) — Enable fast client-side navigation with the built-in `next/link`…

prefetchInlining

boolean | { maxSize?: number; maxBundleSize?: number }

Controls whether prefetch responses are inlined. `true` (default) inlines with default thresholds, `false` disables inlining, or an object customizes the thresholds.

maxSize

Largest a single segment response can be to still be eligible for inlining.

maxBundleSize

Largest total size that can be inlined into one bundled prefetch response along a path.


productionBrowserSourceMaps

Summary: Explains how to enable browser source map generation during production builds in Next.js using the productionBrowserSourceMaps configuration flag.

productionBrowserSourceMaps

Source Maps are enabled by default during development. During production builds, they are disabled to prevent you leaking your source on the client, unless you specifically opt-in with the…

module.exports = {
  productionBrowserSourceMaps: true,
}

productionBrowserSourceMaps

Enables browser source map generation during production builds.


next.config.js: proxyClientMaxBodySize

Summary: Configuration option to set a size limit on the buffered request body when using proxy in Next.js, preventing excessive memory usage. Defaults to 10MB.

Introduction

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on GitHub. Last updated October 20, 2025

When proxy is used,…

Options

String format (recommended)

Specify the size using a human-readable string format:

Supported units: b, kb, mb, gb

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    proxyClientMaxBodySize: '1mb',
  },
}

export default nextConfig

Number format

Alternatively, specify the size in bytes as a number:

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    proxyClientMaxBodySize: 1048576, // 1MB in bytes
  },
}

export default nextConfig

Behavior

When a request body exceeds the configured limit:

- Next.js will buffer only the first N bytes (up to the limit)
- A warning will be logged to the console indicating the route that exceeded the…

Example

import { NextRequest, NextResponse } from 'next/server'

export async function proxy(request: NextRequest) {
  // Next.js automatically buffers the body with the configured size limit
  // You can…

import { NextRequest, NextResponse } from 'next/server'

export async function POST(request: NextRequest) {
  // ...and the body is still available in your route handler
  const body = await…

Good to know

- This setting only applies when proxy is used in your application
- The default limit of 10MB is designed to balance memory usage and typical use cases
- The limit applies per-request, not globally…

proxyClientMaxBodySize

Sets a size limit on the buffered request body when proxy is used, preventing excessive memory usage. String format supports units b, kb, mb, gb; number format specifies bytes. If exceeded, only the…


reactCompiler

Summary: This page documents the `reactCompiler` configuration option in Next.js, which enables the React Compiler to automatically optimize component rendering, reducing the need for manual memoization.

How It Works

The React Compiler runs through a Babel plugin. To keep builds fast, Next.js uses a custom SWC optimization that only applies the React Compiler to relevant files—like those with JSX or React…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  reactCompiler: true,
}

export default nextConfig

Annotations

You can configure the compiler to run in "opt-in" mode as follows:

Then, you can annotate specific components or hooks with the `"use memo"` directive from React to opt-in:

> **Note:**  You can…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  reactCompiler: {
    compilationMode: 'annotation',
  },
}

export default nextConfig

export default function Page() {
  'use memo'
  // ...
}

reactCompiler

boolean | { compilationMode?: 'annotation' | 'all' }

Enables the React Compiler. When set to true, the compiler runs on all relevant files. When set to an object with compilationMode: 'annotation', the compiler runs in opt-in mode, requiring 'use memo'…


reactMaxHeadersLength

Summary: This page describes the `reactMaxHeadersLength` option in `next.config.js`, which controls the maximum length of headers emitted by React during prerendering, with a default value of 6000.

reactMaxHeadersLength

During prerendering, React can emit headers that can be added to the response. These can be used to improve performance by allowing the browser to preload resources like fonts, scripts, and…

module.exports = {
  reactMaxHeadersLength: 1000,
}

reactMaxHeadersLength

Maximum length of headers emitted by React during prerendering. Lower this value if a reverse proxy truncates long headers.


next.config.js: reactStrictMode | Next.js

Summary: This page documents the reactStrictMode configuration option in next.config.js, which enables React Strict Mode in Next.js applications, with notes on default behavior and migration options.

reactStrictMode

Good to know: Since Next.js 13.5.1, Strict Mode is true by default with app router, so the above configuration is only necessary for pages. You can still disable Strict Mode by setting…

module.exports = {
  reactStrictMode: true,
}

reactStrictMode

Enables React Strict Mode in the Next.js application. Defaults to true since Next.js 13.5.1 for the app router, but can be set to false to disable.


next.config.js: redirects | Next.js

Summary: Documentation for the `redirects` key in `next.config.js`, which allows redirecting incoming request paths to different destination paths, including path matching, header/cookie/query matching,…

redirects

Redirects allow you to redirect an incoming request path to a different destination path.

To use redirects you can use the `redirects` key in `next.config.js`:

`redirects` can be defined as a…

module.exports = {
  redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}

{
  source: '/old-blog/:path*',
  destination: '/blog/:path*',
  permanent: false
}

Path Matching

Path matches are allowed, for example `/old-blog/:slug` will match `/old-blog/first-post` (no nested paths):

The pattern `/old-blog/:slug` matches `/old-blog/first-post` and `/old-blog/post-1` but…

module.exports = {
  redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent:…

Wildcard Path Matching

To match a wildcard path you can use `*` after a parameter, for example `/blog/:slug*` will match `/blog/a/b/c/d/hello-world`:

module.exports = {
  redirects() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Matched parameters can be used in the destination
        permanent:…

Regex Path Matching

To match a regex path you can wrap the regex in parentheses after a parameter, for example `/post/:slug(\d{1,})` will match `/post/123` but not `/post/abc`:

The following characters `(`, `)`, `{`,…

module.exports = {
  redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Matched parameters can be used in the destination…

module.exports = {
  redirects() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        destination:…

Header, Cookie, and Query Matching

To only match a redirect when header, cookie, or query values also match the `has` field or don't match the `missing` field can be used. Both the `source` and all `has` items must match and all…

module.exports = {
  redirects() {
    return [
      // if the header `x-redirect-me` is present,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',…

Redirects with basePath support

When leveraging [`basePath` support](/docs/app/api-reference/config/next-config-js/basePath) with redirects each `source` and `destination` is automatically prefixed with the `basePath` unless you…

module.exports = {
  basePath: '/docs',

  redirects() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', //…

Redirects with i18n support

When implementing redirects with internationalization in the App Router, you can include locales in `next.config.js` redirects, but only as hardcoded paths.

For dynamic or per-request locale…

module.exports = {
  redirects() {
    return [
      {
        // Manually handle locale prefixes for App Router
        source: '/en/old-path',
        destination: '/en/new-path',…

Other Redirects

- Inside [API Routes](/docs/pages/building-your-application/routing/api-routes) and [Route Handlers](/docs/app/api-reference/file-conventions/route), you can redirect based on the incoming request.
-…

Version History

| Version | Changes |
| --- | --- |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | `redirects` added. |

source

The incoming request path pattern.

destination

The path you want to route to.

permanent

If `true` will use the 308 status code which instructs clients/search engines to cache the redirect forever, if `false` will use the 307 status code which is temporary and is not cached.

basePath

If false the `basePath` won't be included when matching, can be used for external redirects only.

locale

Whether the locale should not be included when matching.

has

Array<{ type: 'header' | 'cookie' | 'host' | 'query', key: string, value?: string }>

An array of has objects with the `type`, `key` and `value` properties. Both the `source` and all `has` items must match for the redirect to be applied.

missing

An array of missing objects with the `type`, `key` and `value` properties. All `missing` items must not match for the redirect to be applied.

statusCode

A custom status code for older HTTP Clients to properly redirect. Can be used instead of the `permanent` property, but not both. To ensure IE11 compatibility, a `Refresh` header is automatically…


next.config.js: rewrites | Next.js

Summary: Documentation for the rewrites configuration option in next.config.js, which allows mapping incoming request paths to different destination paths, acting as a URL proxy.

rewrites

Rewrites allow you to map an incoming request path to a different destination path. Rewrites act as a URL proxy and mask the destination path, making it appear the user hasn't changed their location…

module.exports = {
  rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ]
  },
}

Rewrite properties

The following properties are available on each rewrite object:

Rewrites array vs object

When the `rewrites` function returns an array, rewrites are applied after checking the filesystem (pages and `/public` files) and before dynamic routes. When the `rewrites` function returns an object…

module.exports = {
  rewrites() {
    return {
      beforeFiles: [
        // These rewrites are checked after headers/redirects
        // and before all files including _next/public files which…

Order of checks

The order Next.js routes are checked is: headers are checked/applied, redirects are checked/applied, proxy, `beforeFiles` rewrites: for each entry, if `source`, `has`, and `missing` matches the…

Rewrite parameters

When using parameters in a rewrite the parameters will be passed in the query by default when none of the parameters are used in the `destination`. If a parameter is used in the destination none of…

module.exports = {
  rewrites() {
    return [
      {
        source: '/old-about/:path*',
        destination: '/about', // The :path parameter isn't used here so will be automatically passed in…

module.exports = {
  rewrites() {
    return [
      {
        source: '/docs/:path*',
        destination: '/:path*', // The :path parameter is used here so will not be automatically passed in the…

module.exports = {
  rewrites() {
    return [
      {
        source: '/:first/:second',
        destination: '/:first?second=:second',
        // Since the :first parameter is used in the…

Path Matching

Path matches are allowed, for example `/blog/:slug` will match `/blog/first-post` (no nested paths). The pattern `/blog/:slug` matches `/blog/first-post` and `/blog/post-1` but not `/blog/a/b` (no…

module.exports = {
  rewrites() {
    return [
      {
        source: '/blog/:slug',
        destination: '/news/:slug', // Matched parameters can be used in the destination
      },
    ]
  },
}

Wildcard Path Matching

To match a wildcard path you can use `*` after a parameter, for example `/blog/:slug*` will match `/blog/a/b/c/d/hello-world`.

module.exports = {
  rewrites() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Matched parameters can be used in the destination
      },
    ]
  },
}

Regex Path Matching

To match a regex path you can wrap the regex in parenthesis after a parameter, for example `/blog/:slug(\d{1,})` will match `/blog/123` but not `/blog/abc`. The following characters `(`, `)`, `{`,…

module.exports = {
  rewrites() {
    return [
      {
        source: '/old-blog/:post(\d{1,})',
        destination: '/blog/:post', // Matched parameters can be used in the destination
      },…

module.exports = {
  rewrites() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\(default\)/:slug',
        destination:…

Header, Cookie, and Query Matching

To only match a rewrite when header, cookie, or query values also match the `has` field or don't match the `missing` field can be used. Both the `source` and all `has` items must match and all…

module.exports = {
  rewrites() {
    return [
      // if the header `x-rewrite-me` is present,
      // this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {…

Rewriting to an external URL

Rewrites allow you to rewrite to an external URL. This is especially useful for incrementally adopting Next.js. The following is an example rewrite for redirecting the `/blog` route of your main app…

module.exports = {
  rewrites() {
    return [
      {
        source: '/blog',
        destination: 'https://example.com/blog',
      },
      {
        source: '/blog/:slug',
        destination:…

module.exports = {
  trailingSlash: true,
  rewrites() {
    return [
      {
        source: '/blog/',
        destination: 'https://example.com/blog/',
      },
      {
        source:…

Incremental adoption of Next.js

You can also have Next.js fall back to proxying to an existing website after checking all Next.js routes. This way you don't have to change the rewrites configuration when migrating more pages to…

module.exports = {
  rewrites() {
    return {
      fallback: [
        {
          source: '/:path*',
          destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
        },…

Rewrites with basePath support

When leveraging `basePath` support with rewrites each `source` and `destination` is automatically prefixed with the `basePath` unless you add `basePath: false` to the rewrite.

module.exports = {
  basePath: '/docs',

  rewrites() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', //…

Version History

| Version | Changes |
| --- | --- |
| `v13.3.0` | `missing` added. |
| `v10.2.0` | `has` added. |
| `v9.5.0` | Headers added. |

source

The incoming request path pattern.

destination

The path you want to route to.

basePath

If false the basePath won't be included when matching, can be used for external rewrites only.

has

An array of has objects with the type, key and value properties.

missing

An array of missing objects with the type, key and value properties.


next.config.js: sassOptions | Next.js

Summary: Reference for the `sassOptions` configuration option in next.config.js, which allows you to configure the Sass compiler.

sassOptions

`sassOptions` allow you to configure the Sass compiler.

> **Good to know:**
> - `sassOptions` are not typed outside of `implementation` because Next.js does not maintain the other possible…

import type { NextConfig } from 'next'

const sassOptions = {
  additionalData: `
    $var: red;
  `,
}

const nextConfig: NextConfig = {
  sassOptions: {
    ...sassOptions,
    implementation:…

sassOptions

Options passed to the Sass compiler.

sassOptions.implementation

Specifies the Sass implementation to use, e.g. 'sass-embedded'.

sassOptions.additionalData

Additional data to prepend to every Sass file, e.g. Sass variables.

sassOptions.functions

Custom Sass functions. Only supported with webpack; not available with Turbopack.


serverActions

Summary: Options for configuring Server Actions behavior in Next.js application, including allowed origins and body size limit.

allowedOrigins

A list of extra safe origin domains from which Server Actions can be invoked. Next.js compares the origin of a Server Action request with the host domain, ensuring they match to prevent CSRF attacks.…

/** @type {import('next').NextConfig} */

module.exports = {
  experimental: {
    serverActions: {
      allowedOrigins: ['my-proxy.com', '*.my-proxy.com'],
    },
  },
}

bodySizeLimit

By default, the maximum size of the request body sent to a Server Action is 1MB, to prevent the consumption of excessive server resources in parsing large amounts of data, as well as potential DDoS…

/** @type {import('next').NextConfig} */

module.exports = {
  experimental: {
    serverActions: {
      bodySizeLimit: '2mb',
    },
  },
}

Enabling Server Actions (v13)

Server Actions became a stable feature in Next.js 14, and are enabled by default. However, if you are using an earlier version of Next.js, you can enable them by setting `experimental.serverActions`…

/** @type {import('next').NextConfig} */
const config = {
  experimental: {
    serverActions: true,
  },
}

module.exports = config

bodySizeLimit

The maximum size of the request body sent to a Server Action. Defaults to 1MB. Can take the number of bytes or any string format supported by bytes, e.g. '500kb' or '3mb'. The limit applies to the…

serverActions

In Next.js 13, set to true to enable Server Actions. In Next.js 14 and later, Server Actions are enabled by default and this option is not needed.


serverComponentsHmrCache

Summary: The experimental `serverComponentsHmrCache` option allows you to cache `fetch` responses in Server Components across HMR refreshes in local development, improving performance and reducing API costs.

serverComponentsHmrCache

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on GitHub.

The experimental `serverComponentsHmrCache` option…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    serverComponentsHmrCache: false, // defaults to true
  },
}

export default nextConfig

serverComponentsHmrCache

When set to false, disables the HMR cache for fetch responses in Server Components during development.


serverExternalPackages

Summary: Describes the `serverExternalPackages` configuration option in Next.js, which allows opting out specific dependencies from Server Components bundling to use native Node.js require.

serverExternalPackages

Dependencies used inside [Server Components](/docs/app/getting-started/server-and-client-components) and [Route Handlers](/docs/app/api-reference/file-conventions/route) will automatically be bundled…

/** @type {import('next').NextConfig} */
const nextConfig = {
  serverExternalPackages: ['@acme/ui'],
}

module.exports = nextConfig


staleTimes

Summary: This page documents the experimental `staleTimes` configuration option in `next.config.js`, which controls client cache revalidation times for dynamic and static page segments.

staleTimes

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on…

/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    staleTimes: {
      dynamic: 30,
      static: 180,
    },
  },
}

module.exports = nextConfig

Version History

| Version | Changes |
| --- | --- |
| `v15.0.0` | The `dynamic` `staleTimes` default changed from 30s to 0s. |
| `v14.2.0` | Experimental `staleTimes` introduced. |

dynamic

Used when the page is neither statically generated nor fully prefetched (e.g. with `prefetch={true}`). Default: 0 seconds (not cached).

static

Used for statically generated pages, or when the `prefetch` prop on `Link` is set to `true`, or when calling `router.prefetch`. Default: 5 minutes.


next.config.js: staticGeneration*

Summary: Explains the experimental `staticGeneration*` options in `next.config.js` that configure the Static Generation process, including retry count, maximum concurrency per worker, and minimum pages per…

staticGeneration*

This feature is currently experimental and subject to change, it's not recommended for production. Try it out and share your feedback on GitHub. The `staticGeneration*` options allow you to configure…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    staticGenerationRetryCount: 1,
    staticGenerationMaxConcurrency: 8,…

Config Options

The following options are available:

- `staticGenerationRetryCount`: The number of times to retry a failed page generation before failing the build.
- `staticGenerationMaxConcurrency`: The maximum…

staticGenerationMaxConcurrency

The maximum number of pages to be processed per worker.

staticGenerationMinPagesPerWorker

The minimum number of pages to be processed before starting a new worker.


next.config.js: supportsImmutableAssets | Next.js

Summary: This page describes the `supportsImmutableAssets` configuration option in next.config.js, used primarily by adapter authors to opt out of immutable static assets when an adapter has enabled support…

supportsImmutableAssets

**Attention**: This option is primarily intended for [adapter](/docs/app/api-reference/adapters) authors. App developers should only set it when troubleshooting adapter-specific issues.

**Enabling…

/** @type {import('next').NextConfig} */
const nextConfig = {
  supportsImmutableAssets: false,
}

module.exports = nextConfig

Version History

| Version | Changes |
| --- | --- |
| `v16.3.0` | Added support for immutable static assets. |

supportsImmutableAssets

Set to `false` to opt out of immutable static assets when your adapter has enabled support for them. If the adapter has not enabled this feature, this option has no effect.


next.config.js: taint | Next.js

Summary: Explains the experimental `taint` configuration option in Next.js, which enables React APIs for tainting objects and values to prevent sensitive data from being sent to the client. Includes usage,…

Usage

The `taint` option enables support for experimental React APIs for tainting objects and values. This feature helps prevent sensitive data from being accidentally passed to the client. When enabled,…

import type { NextConfig } from 'next'

const nextConfig: NextConfig = {
  experimental: {
    taint: true,
  },
}

export default nextConfig

Caveats

Tainting can only keep track of objects by reference. Copying an object creates an untainted version, which loses all guarantees given by the API. You'll need to taint the copy.

Tainting cannot keep…

Examples

Tainting an object reference

In this case, the `getUserDetails` function returns data about a given user. We taint the user object reference, so that it cannot cross a Server-Client boundary. For example, assuming `UserCard` is…

import { experimental_taintObjectReference } from 'react'

function getUserDetails(id: string): UserDetails {
  const user = await db.queryUserById(id)

  experimental_taintObjectReference(
    'Do…

export async function ContactPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const { id } = await params
  const userDetails = await getUserDetails(id)

  return (
    <UserCard…

export async function ContactPage({
  params,
}: {
  params: Promise<{ id: string }>
}) {
  const userDetails = await getUserDetails(id)

  // Throws an error
  return <UserCard user={userDetails}…

Tainting a unique value

In this case, we can access the server configuration by awaiting calls to `config.getConfigDetails`. However, the system configuration contains the `SERVICE_API_KEY` that we don't want to expose to…

import { experimental_taintUniqueValue } from 'react'

function getSystemConfig(): SystemConfig {
  const config = await config.getConfigDetails()

  experimental_taintUniqueValue(
    'Do not pass…

export async function Dashboard() {
  const systemConfig = await getSystemConfig()

  return <ClientDashboard version={systemConfig.SERVICE_API_VERSION} />
}

export async function Dashboard() {
  const systemConfig = await getSystemConfig()
  // Someone makes a mistake in a PR
  const version = systemConfig.SERVICE_API_KEY

  return <ClientDashboard…

export async function Dashboard() {
  const systemConfig = await getSystemConfig()
  // Someone makes a mistake in a PR
  const version = `version::${systemConfig.SERVICE_API_KEY}`

  return…


trailingSlash

Summary: Describes the `trailingSlash` configuration option in Next.js, which controls whether URLs with trailing slashes are redirected to non-trailing-slash versions or vice versa, with exceptions for…

trailingSlash

By default Next.js will redirect URLs with trailing slashes to their counterpart without a trailing slash. For example `/about/` will redirect to `/about`. You can configure this behavior to act the…

module.exports = {
  trailingSlash: true,
}

Version History

| Version | Changes |
| --- | --- |
| `v9.5.0` | `trailingSlash` added. |

trailingSlash

When true, URLs without trailing slashes are redirected to their counterparts with trailing slashes. When false (default), URLs with trailing slashes are redirected to their counterparts without…


transpilePackages

Summary: Use transpilePackages to compile and bundle a dependency instead of treating it as untouched runtime code. This page explains when the option is needed and provides configuration examples.

Overview

Use `transpilePackages` to compile and bundle a dependency instead of treating it as untouched runtime code. Values are package names, including scoped names like `@scope/pkg`. Paths and glob…

/** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['package-name', '@scope/pkg'],
}

module.exports = nextConfig

When you need it

Turbopack transpiles workspace packages (npm, pnpm, or Yarn workspaces) in your monorepo automatically under both routers. Webpack does the same for the App Router. Add a package to…

Version History

| Version | Changes |
| --- | --- |
| `v13.0.0` | `transpilePackages` added. |

transpilePackages

Package names to compile and bundle a dependency instead of treating it as untouched runtime code. Values are package names, including scoped names like `@scope/pkg`. Paths and glob patterns are not…