// Add ?from=/incoming-url to the /login URL
loginUrl.searchParams.set('from', request.nextUrl.pathname)
// And redirect to the new URL
return NextResponse.redirect(loginUrl)
rewrite()
Produce a response that rewrites (proxies) the given URL while preserving the original URL.
 import { NextResponse } from 'next/server'

// Incoming request: /about, browser shows /about
// Rewritten request: /proxy, browser shows /about
return NextResponse.rewrite(new URL('/proxy', request.url))
next()
The next() method is useful for Middleware, as it allows you to return early and continue routing.
 import { NextResponse } from 'next/server'

return NextResponse.next()
You can also forward headers when producing the response:
 import { NextResponse } from 'next/server'

// Given an incoming request...


import { NextResponse } from 'next/server'

// Given an incoming request...
const newHeaders = new Headers(request.headers)
// Add a new header
newHeaders.set('x-version', '123')
// And produce a response with the new headers
return NextResponse.next({
  request: {
    // New request headers
    headers: newHeaders,
  },
})


httpAgentOptions
In Node.js versions prior to 18, Next.js automatically polyfills fetch() with node-fetch and enables HTTP Keep-Alive by default.
To disable HTTP Keep-Alive for all fetch() calls on the server-side, open next.config.js and add the httpAgentOptions config:
next.config.js module.exports = {
  httpAgentOptions: {
    keepAlive: false,
  },
}


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 on the site. In contrast, redirects will reroute to a new page and show the URL changes.
To use rewrites you can use the rewrites key in next.config.js:
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        source: '/about',
        destination: '/',
      },
    ]
  },
}
Rewrites are applied to client-side routing, a <Link href="/about"> will have the rewrite applied in the above example.
rewrites is an async function that expects to return either an array or an object of arrays (see below) holding objects with source and destination properties:
source: String - is the incoming request path pattern.


source: String - is the incoming request path pattern.
destination: String is the path you want to route to.
basePath: false or undefined - if false the basePath won't be included when matching, can be used for external rewrites only.
locale: false or undefined - whether the locale should not be included when matching.
has is an array of has objects with the type, key and value properties.
missing is an array of missing objects with the type, key and value properties.
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 of arrays with a specific shape, this behavior can be changed and more finely controlled, as of v10.1 of Next.js:
next.config.js module.exports = {
  async rewrites() {
    return {
      beforeFiles: [


async rewrites() {
    return {
      beforeFiles: [
        // These rewrites are checked after headers/redirects
        // and before all files including _next/public files which
        // allows overriding page files
        {
          source: '/some-page',
          destination: '/somewhere-else',
          has: [{ type: 'query', key: 'overrideMe' }],
        },
      ],
      afterFiles: [
        // These rewrites are checked after pages/public files
        // are checked but before dynamic routes
        {
          source: '/non-existent',
          destination: '/somewhere-else',
        },
      ],
      fallback: [
        // These rewrites are checked after both pages/public files
        // and dynamic routes are checked
        {
          source: '/:path*',


// and dynamic routes are checked
        {
          source: '/:path*',
          destination: `https://my-old-site.com/:path*`,
        },
      ],
    }
  },
}
Good to know: rewrites in beforeFiles do not check the filesystem/dynamic routes immediately after matching a source, they continue until all beforeFiles have been checked.
The order Next.js routes are checked is:
headers are checked/applied
redirects are checked/applied
beforeFiles rewrites are checked/applied
static files from the public directory, _next/static files, and non-dynamic pages are checked/served
afterFiles rewrites are checked/applied, if one of these rewrites is matched we check dynamic routes/static files after each match


fallback rewrites are checked/applied, these are applied before rendering the 404 page and after dynamic routes/all static assets have been checked. If you use fallback: true/'blocking' in getStaticPaths, the fallback rewrites defined in your next.config.js will not be run.
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.
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        source: '/old-about/:path*',
        destination: '/about', // The :path parameter isn't used here so will be automatically passed in the query
      },
    ]
  },
}
If a parameter is used in the destination none of the parameters will be automatically passed in the query.
next.config.js module.exports = {
  async rewrites() {
    return [
      {


async rewrites() {
    return [
      {
        source: '/docs/:path*',
        destination: '/:path*', // The :path parameter is used here so will not be automatically passed in the query
      },
    ]
  },
}
You can still pass the parameters manually in the query if one is already used in the destination by specifying the query in the destination.
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        source: '/:first/:second',
        destination: '/:first?second=:second',
        // Since the :first parameter is used in the destination the :second parameter
        // will not automatically be added in the query although we can manually add it
        // as shown above
      },
    ]
  },
}


// as shown above
      },
    ]
  },
}
Good to know: Static pages from Automatic Static Optimization or prerendering params from rewrites will be parsed on the client after hydration and provided in the query.
Path Matching
Path matches are allowed, for example /blog/:slug will match /blog/hello-world (no nested paths):
next.config.js module.exports = {
  async 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:
next.config.js module.exports = {
  async rewrites() {
    return [
      {


async 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:
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        source: '/old-blog/:post(\\d{1,})',
        destination: '/blog/:post', // Matched parameters can be used in the destination
      },
    ]
  },
}


},
    ]
  },
}
The following characters (, ), {, }, :, *, +, ? are used for regex path matching, so when used in the source as non-special values they must be escaped by adding \\ before them:
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        destination: '/en-us/:slug',
      },
    ]
  },
}
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 missing items must not match for the rewrite to be applied.
has and missing items can have the following fields:


has and missing items can have the following fields:
type: String - must be either header, cookie, host, or query.
key: String - the key from the selected type to match against.
value: String or undefined - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value first-(?<paramName>.*) is used for first-second then second will be usable in the destination with :paramName.
next.config.js module.exports = {
  async rewrites() {
    return [
      // if the header `x-rewrite-me` is present,
      // this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-rewrite-me',
          },
        ],


key: 'x-rewrite-me',
          },
        ],
        destination: '/another-page',
      },
      // if the header `x-rewrite-me` is not present,
      // this rewrite will be applied
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-rewrite-me',
          },
        ],
        destination: '/another-page',
      },
      // if the source, query, and cookie are matched,
      // this rewrite will be applied
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // the page value will not be available in the
            // destination since value is provided and doesn't
            // use a named capture group e.g. (?<page>home)


// use a named capture group e.g. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        destination: '/:path*/home',
      },
      // if the header `x-authorized` is present and
      // contains a matching value, this rewrite will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        destination: '/home?authorized=:authorized',
      },
      // if the host is `example.com`,
      // this rewrite will be applied
      {
        source: '/:path*',
        has: [


{
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        destination: '/another-page',
      },
    ]
  },
}
Rewriting to an external URL
Examples
Incremental adoption of Next.js
Using Multiple Zones
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 to an external site.
next.config.js module.exports = {
  async rewrites() {
    return [
      {
        source: '/blog',
        destination: 'https://example.com/blog',
      },
      {
        source: '/blog/:slug',


},
      {
        source: '/blog/:slug',
        destination: 'https://example.com/blog/:slug', // Matched parameters can be used in the destination
      },
    ]
  },
}
If you're using trailingSlash: true, you also need to insert a trailing slash in the source parameter. If the destination server is also expecting a trailing slash it should be included in the destination parameter as well.
next.config.js module.exports = {
  trailingSlash: true,
  async rewrites() {
    return [
      {
        source: '/blog/',
        destination: 'https://example.com/blog/',
      },
      {
        source: '/blog/:path*/',
        destination: 'https://example.com/blog/:path*/',
      },
    ]
  },
}
Incremental adoption of Next.js


},
    ]
  },
}
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 Next.js
next.config.js module.exports = {
  async 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:
next.config.js module.exports = {
  basePath: '/docs',

  async rewrites() {
    return [
      {


async rewrites() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', // automatically becomes /docs/another
      },
      {
        // does not add /docs to /without-basePath since basePath: false is set
        // Note: this can not be used for internal rewrites e.g. `destination: '/another'`
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
      },
    ]
  },
}
Rewrites with i18n support
When leveraging i18n support with rewrites each source and destination is automatically prefixed to handle the configured locales unless you add locale: false to the rewrite. If locale: false is used you must prefix the source and destination with a locale for it to be matched correctly.


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

  async rewrites() {
    return [
      {
        source: '/with-locale', // automatically handles all locales
        destination: '/another', // automatically passes the locale on
      },
      {
        // does not handle locales automatically since locale: false is set
        source: '/nl/with-locale-manual',
        destination: '/nl/another',
        locale: false,
      },
      {
        // this matches '/' since `en` is the defaultLocale
        source: '/en',
        destination: '/en/another',
        locale: false,
      },
      {
        // it's possible to match all locales even when locale: false is set


{
        // it's possible to match all locales even when locale: false is set
        source: '/:locale/api-alias/:path*',
        destination: '/api/:path*',
        locale: false,
      },
      {
        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level
        // `/` or `/fr` routes like /:path* would
        source: '/(.*)',
        destination: '/another',
      },
    ]
  },
}
Version History
VersionChangesv13.3.0missing added.v10.2.0has added.v9.5.0Headers added.


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 instead of '' (an empty string, the default), open next.config.js and add the basePath config:
next.config.js module.exports = {
  basePath: '/docs',
}
Good to know: This value must be set at build time and cannot be changed without re-building as the value is inlined in the client-side bundles.
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 set to /docs.
 export default function HomePage() {
  return (
    <>
      <Link href="/about">About Page</Link>
    </>
  )
}
Output html:


</>
  )
}
Output html:
 About Page
This makes sure that you don't have to change all links in your application when changing the basePath value.
Images
When using the next/image component, you will need to add the basePath in front of src.
For example, using /docs/me.png will properly serve your image when basePath is set to /docs.
 import Image from 'next/image'

function Home() {
  return (
    <>

My Homepage

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

Welcome to my homepage!

    </>
  )
}

export default Home


eslint
When ESLint is detected in your project, Next.js fails your production build (next build) when errors are present.
If you'd like Next.js to produce production code even when your application has ESLint errors, you can disable the built-in linting step completely. This is not recommended unless you already have ESLint configured to run in a separate part of your workflow (for example, in CI or a pre-commit hook).
Open next.config.js and enable the ignoreDuringBuilds option in the eslint config:
next.config.js module.exports = {
  eslint: {
    // Warning: This allows production builds to successfully complete even if
    // your project has ESLint errors.
    ignoreDuringBuilds: true,
  },
}


Runtime Config
Good to know: This feature is considered legacy and does not work with Automatic Static Optimization, Output File Tracing, or React Server Components. Please use environment variables instead to avoid initialization overhead.
To add runtime configuration to your app, open next.config.js and add the publicRuntimeConfig and serverRuntimeConfig configs:
next.config.js module.exports = {
  serverRuntimeConfig: {
    // Will only be available on the server side
    mySecret: 'secret',
    secondSecret: process.env.SECOND_SECRET, // Pass through env variables
  },
  publicRuntimeConfig: {
    // Will be available on both server and client
    staticFolder: '/static',
  },
}
Place any server-only runtime config under serverRuntimeConfig.
Anything accessible to both client and server-side code should be under publicRuntimeConfig.


Anything accessible to both client and server-side code should be under publicRuntimeConfig.
A page that relies on publicRuntimeConfig must use getInitialProps or getServerSideProps or your application must have a Custom App with getInitialProps to opt-out of Automatic Static Optimization. Runtime configuration won't be available to any page (or component in a page) without being server-side rendered.
To get access to the runtime configs in your app use next/config, like so:
 import getConfig from 'next/config'
import Image from 'next/image'

// Only holds serverRuntimeConfig and publicRuntimeConfig
const { serverRuntimeConfig, publicRuntimeConfig } = getConfig()
// Will only be available on the server-side
console.log(serverRuntimeConfig.mySecret)
// Will be available on both server-side and client-side
console.log(publicRuntimeConfig.staticFolder)

function MyImage() {
  return (
    <div>
      <Image


function MyImage() {
  return (
    <div>
      <Image
        src={`${publicRuntimeConfig.staticFolder}/logo.png`}
        alt="logo"
        layout="fill"
      />
    </div>
  )
}

export default MyImage


incrementalCacheHandlerPathIn Next.js, the default cache handler uses the filesystem cache. This requires no configuration, however, you can customize the cache handler by using the incrementalCacheHandlerPath field in next.config.js.
next.config.js module.exports = {
  experimental: {
    incrementalCacheHandlerPath: require.resolve('./cache-handler.js'),
  },
}
Here's an example of a custom cache handler:
cache-handler.js const cache = new Map()

module.exports = class CacheHandler {
  constructor(options) {
    this.options = options
    this.cache = {}
  }

  async get(key) {
    return cache.get(key)
  }

  async set(key, data) {
    cache.set(key, {
      value: data,
      lastModified: Date.now(),
    })
  }
}
API Reference


lastModified: Date.now(),
    })
  }
}
API Reference
The cache handler can implement the following methods: get, set, and revalidateTag.
get()
ParameterTypeDescriptionkeystringThe key to the cached value.
Returns the cached value or null if not found.
set()
ParameterTypeDescriptionkeystringThe key to store the data under.dataData or nullThe data to be cached.
Returns Promise<void>.
revalidateTag()
ParameterTypeDescriptiontagstringThe cache tag to revalidate.
Returns Promise<void>. Learn more about revalidating data or the revalidateTag() function.


transpilePackages
Next.js can automatically transpile and bundle dependencies from local packages (like monorepos) or from external dependencies (node_modules). This replaces the next-transpile-modules package.
next.config.js /** @type {import('next').NextConfig} */
const nextConfig = {
  transpilePackages: ['@acme/ui', 'lodash-es'],
}

module.exports = nextConfig
Version History
VersionChangesv13.0.0transpilePackages added.


generateEtags
Next.js will generate etags for every page by default. You may want to disable etag generation for HTML pages depending on your cache strategy.
Open next.config.js and disable the generateEtags option:
next.config.js module.exports = {
  generateEtags: false,
}


appDir
Good to know: This option is no longer needed as of Next.js 13.4. The App Router is now stable.
The App Router (app directory) enables support for layouts, Server Components, streaming, and colocated data fetching.
Using the app directory will automatically enable React Strict Mode. Learn how to incrementally adopt app.


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:
next.config.js module.exports = {
  async redirects() {
    return [
      {
        source: '/about',
        destination: '/',
        permanent: true,
      },
    ]
  },
}
redirects is an async function that expects an array to be returned holding objects with source, destination, and permanent properties:
source is the incoming request path pattern.
destination is the path you want to route to.
permanent true or false - 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.


Why does Next.js use 307 and 308? Traditionally a 302 was used for a temporary redirect, and a 301 for a permanent redirect, but many browsers changed the request method of the redirect to GET, regardless of the original method. For example, if the browser made a request to POST /v1/users which returned status code 302 with location /v2/users, the subsequent request might be GET /v2/users instead of the expected POST /v2/users. Next.js uses the 307 temporary redirect, and 308 permanent redirect status codes to explicitly preserve the request method used.
basePath: false or undefined - if false the basePath won't be included when matching, can be used for external redirects only.
locale: false or undefined - whether the locale should not be included when matching.
has is an array of has objects with the type, key and value properties.


has is an array of has objects with the type, key and value properties.
missing is an array of missing objects with the type, key and value properties.
Redirects are checked before the filesystem which includes pages and /public files.
Redirects are not applied to client-side routing (Link, router.push), unless Middleware is present and matches the path.
When a redirect is applied, any query values provided in the request will be passed through to the redirect destination. For example, see the following redirect configuration:
 {
  source: '/old-blog/:path*',
  destination: '/blog/:path*',
  permanent: false
}
When /old-blog/post-1?hello=world is requested, the client will be redirected to /blog/post-1?hello=world.
Path Matching
Path matches are allowed, for example /old-blog/:slug will match /old-blog/hello-world (no nested paths):


next.config.js module.exports = {
  async redirects() {
    return [
      {
        source: '/old-blog/:slug',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent: true,
      },
    ]
  },
}
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:
next.config.js module.exports = {
  async redirects() {
    return [
      {
        source: '/blog/:slug*',
        destination: '/news/:slug*', // Matched parameters can be used in the destination
        permanent: true,
      },
    ]
  },
}
Regex Path Matching


},
    ]
  },
}
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:
next.config.js module.exports = {
  async redirects() {
    return [
      {
        source: '/post/:slug(\\d{1,})',
        destination: '/news/:slug', // Matched parameters can be used in the destination
        permanent: false,
      },
    ]
  },
}
The following characters (, ), {, }, :, *, +, ? are used for regex path matching, so when used in the source as non-special values they must be escaped by adding \\ before them:
next.config.js module.exports = {
  async redirects() {
    return [
      {


async redirects() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        destination: '/en-us/:slug',
        permanent: false,
      },
    ]
  },
}
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 missing items must not match for the redirect to be applied.
has and missing items can have the following fields:
type: String - must be either header, cookie, host, or query.
key: String - the key from the selected type to match against.


key: String - the key from the selected type to match against.
value: String or undefined - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value first-(?<paramName>.*) is used for first-second then second will be usable in the destination with :paramName.
next.config.js module.exports = {
  async redirects() {
    return [
      // if the header `x-redirect-me` is present,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'header',
            key: 'x-redirect-me',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },


],
        permanent: false,
        destination: '/another-page',
      },
      // if the header `x-dont-redirect` is present,
      // this redirect will NOT be applied
      {
        source: '/:path((?!another-page$).*)',
        missing: [
          {
            type: 'header',
            key: 'x-do-not-redirect',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
      // if the source, query, and cookie are matched,
      // this redirect will be applied
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // the page value will not be available in the
            // destination since value is provided and doesn't


// destination since value is provided and doesn't
            // use a named capture group e.g. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        permanent: false,
        destination: '/another/:path*',
      },
      // if the header `x-authorized` is present and
      // contains a matching value, this redirect will be applied
      {
        source: '/',
        has: [
          {
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        permanent: false,
        destination: '/home?authorized=:authorized',
      },
      // if the host is `example.com`,


},
      // if the host is `example.com`,
      // this redirect will be applied
      {
        source: '/:path((?!another-page$).*)',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        permanent: false,
        destination: '/another-page',
      },
    ]
  },
}
Redirects with basePath support
When leveraging basePath support with redirects each source and destination is automatically prefixed with the basePath unless you add basePath: false to the redirect:
next.config.js module.exports = {
  basePath: '/docs',

  async redirects() {
    return [
      {
        source: '/with-basePath', // automatically becomes /docs/with-basePath
        destination: '/another', // automatically becomes /docs/another
        permanent: false,
      },


permanent: false,
      },
      {
        // does not add /docs since basePath: false is set
        source: '/without-basePath',
        destination: 'https://example.com',
        basePath: false,
        permanent: false,
      },
    ]
  },
}
Redirects with i18n support
When leveraging i18n support with redirects each source and destination is automatically prefixed to handle the configured locales unless you add locale: false to the redirect. If locale: false is used you must prefix the source and destination with a locale for it to be matched correctly.
next.config.js module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },

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


{
        source: '/with-locale', // automatically handles all locales
        destination: '/another', // automatically passes the locale on
        permanent: false,
      },
      {
        // does not handle locales automatically since locale: false is set
        source: '/nl/with-locale-manual',
        destination: '/nl/another',
        locale: false,
        permanent: false,
      },
      {
        // this matches '/' since `en` is the defaultLocale
        source: '/en',
        destination: '/en/another',
        locale: false,
        permanent: false,
      },
      // it's possible to match all locales even when locale: false is set
      {
        source: '/:locale/page',
        destination: '/en/newpage',
        permanent: false,
        locale: false,
      }
      {


permanent: false,
        locale: false,
      }
      {
        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level
        // `/` or `/fr` routes like /:path* would
        source: '/(.*)',
        destination: '/another',
        permanent: false,
      },
    ]
  },
}
In some rare cases, you might need to assign a custom status code for older HTTP Clients to properly redirect. In these cases, you can use the statusCode property instead of the permanent property, but not both. To to ensure IE11 compatibility, a Refresh header is automatically added for the 308 status code.
Other Redirects
Inside API Routes, you can use res.redirect().
Inside getStaticProps and getServerSideProps, you can redirect specific pages at request-time.
Version History


Version History
VersionChangesv13.3.0missing added.v10.2.0has added.v9.5.0redirects added.


compress
Next.js provides gzip compression to compress rendered content and static files. In general you will want to enable compression on a HTTP proxy like nginx, to offload load from the Node.js process.
To disable compression, open next.config.js and disable the compress config:
next.config.js module.exports = {
  compress: false,
}


serverComponentsExternalPackagesDependencies used inside Server Components and Route Handlers will automatically be bundled by Next.js.
If a dependency is using Node.js specific features, you can choose to opt-out specific dependencies from the Server Components bundling and use native Node.js require.
next.config.js /** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    serverComponentsExternalPackages: ['@acme/ui'],
  },
}

module.exports = nextConfig
Next.js includes a short list of popular packages that currently are working on compatibility and automatically opt-ed out:
@aws-sdk/client-s3
@aws-sdk/s3-presigned-post
@blockfrost/blockfrost-js
@jpg-store/lucid-cardano
@mikro-orm/core
@mikro-orm/knex
@prisma/client
@sentry/nextjs
@sentry/node
@swc/core
argon2


@sentry/nextjs
@sentry/node
@swc/core
argon2
autoprefixer
aws-crt
bcrypt
better-sqlite3
canvas
cpu-features
cypress
eslint
express
firebase-admin
jest
jsdom
lodash
mdx-bundler
mongodb
mongoose
next-mdx-remote
next-seo
payload
pg
playwright
postcss
prettier
prisma
puppeteer
rimraf
sharp
shiki
sqlite3
tailwindcss
ts-node
typescript
vscode-oniguruma
webpack


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 helps reduce the size of deployments drastically. Previously, when deploying with Docker you would need to have all files from your package's dependencies installed to run next start. Starting with Next.js 12, you can leverage Output File Tracing in the .next/ directory to only include the necessary files.
Furthermore, this removes the need for the deprecated serverless target which can cause various issues and also creates unnecessary duplication.
How it Works
During next build, Next.js will use @vercel/nft to statically analyze import, require, and fs usage to determine all files that a page might load.
Next.js' production server is also traced for its needed files and output at .next/next-server.js.nft.json which can be leveraged in production.


To leverage the .nft.json files emitted to the .next output directory, you can read the list of files in each trace that are relative to the .nft.json file and then copy them to your deployment location.
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 you can enable it in your next.config.js:
next.config.js module.exports = {
  output: 'standalone',
}
This will create a folder at .next/standalone which can then be deployed on its own without installing node_modules.


Additionally, a minimal server.js file is also output which can be used instead of next start. This minimal server does not copy the public or .next/static folders by default as these should ideally be handled by a CDN instead, although these folders can be copied to the standalone/public and standalone/.next/static folders manually, after which server.js file will serve these automatically.
Good to know:
next.config.js is read during next build and serialized into the server.js output file. If the legacy serverRuntimeConfig or publicRuntimeConfig options are being used, the values will be specific to values at build time.
If your project uses Image Optimization with the default loader, you must install sharp as a dependency:
If your project needs alternative port or hostname for listening, you can define PORT and HOSTNAME environment variables, before running server.js. For example, PORT=3000 HOSTNAME=localhost node server.js.
Terminal npm i sharp
Terminal yarn add sharp
Terminal pnpm add sharp


Terminal npm i sharp
Terminal yarn add sharp
Terminal pnpm add sharp
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 folder will not be included. To include files outside of this folder you can set experimental.outputFileTracingRoot in your next.config.js.
packages/web-app/next.config.js module.exports = {
  experimental: {
    // this includes files from the monorepo base two directories up
    outputFileTracingRoot: path.join(__dirname, '../../'),
  },
}


outputFileTracingRoot: path.join(__dirname, '../../'),
  },
}
There are some cases in which Next.js might fail to include required files, or might incorrectly include unused files. In those cases, you can leverage experimental.outputFileTracingExcludes and experimental.outputFileTracingIncludes respectively in next.config.js. Each config accepts an object with minimatch globs for the key to match specific pages and a value of an array with globs relative to the project's root to either include or exclude in the trace.
next.config.js module.exports = {
  experimental: {
    outputFileTracingExcludes: {
      '/api/hello': ['./un-necessary-folder/**/*'],
    },
    outputFileTracingIncludes: {
      '/api/another': ['./necessary-folder/**/*'],
    },
  },
}


},
  },
}
Currently, Next.js does not do anything with the emitted .nft.json files. The files must be read by your deployment platform, for example Vercel, to create a minimal deployment. In a future release, a new command is planned to utilize these .nft.json files.
Experimental turbotrace
Tracing dependencies can be slow because it requires very complex computations and analysis. We created turbotrace in Rust as a faster and smarter alternative to the JavaScript implementation.
To enable it, you can add the following configuration to your next.config.js:
next.config.js module.exports = {
  experimental: {
    turbotrace: {
      // control the log level of the turbotrace, default is `error`
      logLevel?:
      | 'bug'
      | 'fatal'
      | 'error'
      | 'warning'
      | 'hint'


| 'error'
      | 'warning'
      | 'hint'
      | 'note'
      | 'suggestions'
      | 'info',
      // control if the log of turbotrace should contain the details of the analysis, default is `false`
      logDetail?: boolean
      // show all log messages without limit
      // turbotrace only show 1 log message for each categories by default
      logAll?: boolean
      // control the context directory of the turbotrace
      // files outside of the context directory will not be traced
      // set the `experimental.outputFileTracingRoot` has the same effect
      // if the `experimental.outputFileTracingRoot` and this option are both set, the `experimental.turbotrace.contextDirectory` will be used
      contextDirectory?: string


contextDirectory?: string
      // if there is `process.cwd()` expression in your code, you can set this option to tell `turbotrace` the value of `process.cwd()` while tracing.
      // for example the require(process.cwd() + '/package.json') will be traced as require('/path/to/cwd/package.json')
      processCwd?: string
      // control the maximum memory usage of the `turbotrace`, in `MB`, default is `6000`.
      memoryLimit?: number
    },
  },
}


generateBuildId
Next.js uses a constant id generated at build time to identify which version of your application is being served. This can cause problems in multi-server deployments when next build is run on every server. In order to keep a consistent build id between builds you can provide your own build id.
Open next.config.js and add the generateBuildId function:
next.config.js module.exports = {
  generateBuildId: async () => {
    // You can, for example, get the latest git commit hash here
    return 'my-build-id'
  },
}


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).next.config.js const withMDX = require('@next/mdx')()

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


experimental: {
    mdxRs: true,
  },
}

module.exports = withMDX(nextConfig)For custom advanced configuration of Next.js, you can create a next.config.js or next.config.mjs file in the root of your project directory (next to package.json).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.Take a look at the following next.config.js example:next.config.js /**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  /* config options here */
}

module.exports = nextConfigIf you need ECMAScript modules, you can use next.config.mjs:next.config.mjs /**
 * @type {import('next').NextConfig}
 */
const nextConfig = {
  /* config options here */


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

export default nextConfigYou can also use a function:next.config.mjs module.exports = (phase, { defaultConfig }) => {
  /**
   * @type {import('next').NextConfig}
   */
  const nextConfig = {
    /* config options here */
  }
  return nextConfig
}Since Next.js 12.1.0, you can use an async function:next.config.js module.exports = async (phase, { defaultConfig }) => {
  /**
   * @type {import('next').NextConfig}
   */
  const nextConfig = {
    /* config options here */
  }
  return nextConfig


/* config options here */
  }
  return nextConfig
}phase is the current context in which the configuration is loaded. You can see the available phases. Phases can be imported from next/constants: const { PHASE_DEVELOPMENT_SERVER } = require('next/constants')

module.exports = (phase, { defaultConfig }) => {
  if (phase === PHASE_DEVELOPMENT_SERVER) {
    return {
      /* development only config options here */
    }
  }

  return {
    /* config options for all phases except development here */
  }


return {
    /* config options for all phases except development here */
  }
}The commented lines are the place where you can put the configs allowed by next.config.js, which are defined in this file.However, none of the configs are required, and it's not necessary to understand what each config does. Instead, search for the features you need to enable or modify in this section and they will show you what to do.
Avoid using new JavaScript features not available in your target Node.js version. next.config.js will not be parsed by Webpack, Babel or TypeScript.


assetPrefix
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 customizable Base Path, which is better
suited for hosting your application on a sub-path like /docs.
We do not suggest you use a custom Asset Prefix for this use case.
To set up a CDN, you can set up an asset prefix and configure your CDN's origin to resolve to the domain that Next.js is hosted on.
Open next.config.js and add the assetPrefix config:
next.config.js const isProd = process.env.NODE_ENV === 'production'

module.exports = {
  // Use the CDN in production and localhost for development.
  assetPrefix: isProd ? 'https://cdn.mydomain.com' : undefined,
}


}
Next.js will automatically use your asset prefix for the JavaScript and CSS files it loads from the /_next/ path (.next/static/ folder). For example, with the above configuration, the following request for a JS chunk:
 /_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js
Would instead become:
 https://cdn.mydomain.com/_next/static/chunks/4b9b41aaa062cbbfeff4add70f256968c51ece5d.4d708494b3aed70c04f0.js


The exact configuration for uploading your files to a given CDN will depend on your CDN of choice. The only folder you need to host on your CDN is the contents of .next/static/, which should be uploaded as _next/static/ as the above URL request indicates. Do not upload the rest of your .next/ folder, as you should not expose your server code and other configuration to the public.
While assetPrefix covers requests to _next/static, it does not influence the following paths:
Files in the public folder; if you want to serve those assets over a CDN, you'll have to introduce the prefix yourself


typedRoutes (experimental)Experimental support for statically typed links. This feature requires using the App Router as well as TypeScript in your project.
next.config.js /** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    typedRoutes: true,
  },
}

module.exports = nextConfig


env
Since the release of Next.js 9.4 we now have a more intuitive and ergonomic experience for adding environment variables. Give it a try!
Examples
With env
Good to know: environment variables specified in this way will always be included in the JavaScript bundle, prefixing the environment variable name with NEXT_PUBLIC_ only has an effect when specifying them through the environment or .env files.
To add environment variables to the JavaScript bundle, open next.config.js and add the env config:
next.config.js module.exports = {
  env: {
    customKey: 'my-value',
  },
}
Now you can access process.env.customKey in your code. For example:
 function Page() {
  return
The value of customKey is: {process.env.customKey}

}

export default Page


}

export default Page
Next.js will replace process.env.customKey with 'my-value' at build time. Trying to destructure process.env variables won't work due to the nature of webpack DefinePlugin.
For example, the following line:
 return
The value of customKey is: {process.env.customKey}

Will end up being:
 return
The value of customKey is: {'my-value'}


webVitalsAttribution
When debugging issues related to Web Vitals, it is often helpful if we can pinpoint the source of the problem.
For example, in the case of Cumulative Layout Shift (CLS), we might want to know the first element that shifted when the single largest layout shift occurred.
Or, in the case of Largest Contentful Paint (LCP), we might want to identify the element corresponding to the LCP for the page.
If the LCP element is an image, knowing the URL of the image resource can help us locate the asset we need to optimize.
Pinpointing the biggest contributor to the Web Vitals score, aka attribution,
allows us to obtain more in-depth information like entries for PerformanceEventTiming, PerformanceNavigationTiming and PerformanceResourceTiming.
Attribution is disabled by default in Next.js but can be enabled per metric by specifying the following in next.config.js.
next.config.js experimental: {


next.config.js experimental: {
  webVitalsAttribution: ['CLS', 'LCP']
}
Valid attribution values are all web-vitals metrics specified in the NextWebVitalsMetric type.


exportPathMap (Deprecated)
This feature is exclusive to next export and currently deprecated in favor of getStaticPaths with pages or generateStaticParams with app.
Examples
Static Export
exportPathMap allows you to specify a mapping of request paths to page destinations, to be used during export. Paths defined in exportPathMap will also be available when using next dev.
Let's start with an example, to create a custom exportPathMap for an app with the following pages:
pages/index.js
pages/about.js
pages/post.js
Open next.config.js and add the following exportPathMap config:
next.config.js module.exports = {
  exportPathMap: async function (
    defaultPathMap,
    { dev, dir, outDir, distDir, buildId }
  ) {
    return {
      '/': { page: '/' },
      '/about': { page: '/about' },


'/about': { page: '/about' },
      '/p/hello-nextjs': { page: '/post', query: { title: 'hello-nextjs' } },
      '/p/learn-nextjs': { page: '/post', query: { title: 'learn-nextjs' } },
      '/p/deploy-nextjs': { page: '/post', query: { title: 'deploy-nextjs' } },
    }
  },
}
Good to know: the query field in exportPathMap cannot be used with automatically statically optimized pages or getStaticProps pages as they are rendered to HTML files at build-time and additional query information cannot be provided during next export.
The pages will then be exported as HTML files, for example, /about will become /about.html.


exportPathMap is an async function that receives 2 arguments: the first one is defaultPathMap, which is the default map used by Next.js. The second argument is an object with:
dev - true when exportPathMap is being called in development. false when running next export. In development exportPathMap is used to define routes.
dir - Absolute path to the project directory
outDir - Absolute path to the out/ directory (configurable with -o). When dev is true the value of outDir will be null.
distDir - Absolute path to the .next/ directory (configurable with the distDir config)
buildId - The generated build id
The returned object is a map of pages where the key is the pathname and the value is an object that accepts the following fields:
page: String - the page inside the pages directory to render


page: String - the page inside the pages directory to render
query: Object - the query object passed to getInitialProps when prerendering. Defaults to {}
The exported pathname can also be a filename (for example, /readme.md), but you may need to set the Content-Type header to text/html when serving its content if it is different than .html.
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 behavior prior to Next.js 9.
To switch back and add a trailing slash, open next.config.js and enable the trailingSlash config:
next.config.js module.exports = {
  trailingSlash: true,
}
Customizing the output directory
next export will use out as the default output directory, you can customize this using the -o argument, like so:


Terminal next export -o outdir
Warning: Using exportPathMap is deprecated and is overridden by getStaticPaths inside pages. We don't recommend using them together.


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:
next.config.js module.exports = {
  images: {
    loader: 'custom',
    loaderFile: './my/image/loader.js',
  },
}
This loaderFile must point to a file relative to the root of your Next.js application. The file must export a default function that returns a string, for example:
 export default function myImageLoader({ src, width, quality }) {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}
Alternatively, you can use the loader prop to pass the function to each instance of next/image.
Example Loader Configuration
Akamai
Cloudinary
Cloudflare
Contentful
Fastly
Gumlet
ImageEngine
Imgix
Thumbor


Contentful
Fastly
Gumlet
ImageEngine
Imgix
Thumbor
Supabase
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}`
}
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', `w_${width}`, `q_${quality || 'auto'}`]
  return `https://example.com/${params.join(',')}${src}`
}
Cloudflare
 // Docs: https://developers.cloudflare.com/images/url-format
export default function cloudflareLoader({ src, width, quality }) {


export default function cloudflareLoader({ src, width, quality }) {
  const params = [`width=${width}`, `quality=${quality || 75}`, 'format=auto']
  return `https://example.com/cdn-cgi/image/${params.join(',')}/${src}`
}
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}`)
  url.searchParams.set('fm', 'webp')
  url.searchParams.set('w', width.toString())
  url.searchParams.set('q', (quality || 75).toString())
  return url.href
}
Fastly
 // Docs: https://developer.fastly.com/reference/io/
export default function fastlyLoader({ src, width, quality }) {


export default function fastlyLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)
  url.searchParams.set('auto', 'webp')
  url.searchParams.set('width', width.toString())
  url.searchParams.set('quality', (quality || 75).toString())
  return url.href
}
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}`)
  url.searchParams.set('format', 'auto')
  url.searchParams.set('w', width.toString())
  url.searchParams.set('q', (quality || 75).toString())
  return url.href
}
ImageEngine


return url.href
}
ImageEngine
 // Docs: https://support.imageengine.io/hc/en-us/articles/360058880672-Directives
export default function imageengineLoader({ src, width, quality }) {
  const compression = 100 - (quality || 50)
  const params = [`w_${width}`, `cmpr_${compression}`)]
  return `https://example.com${src}?imgeng=/${params.join('/')`
}
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 = url.searchParams
  params.set('auto', params.getAll('auto').join(',') || 'format')
  params.set('fit', params.get('fit') || 'max')


params.set('fit', params.get('fit') || 'max')
  params.set('w', params.get('w') || width.toString())
  params.set('q', (quality || 50).toString())
  return url.href
}
Thumbor
 // Docs: https://thumbor.readthedocs.io/en/latest/
export default function thumborLoader({ src, width, quality }) {
  const params = [`${width}x0`, `filters:quality(${quality || 75})`]
  return `https://example.com${params.join('/')}${src}`
}
Supabase
 // Docs: https://supabase.com/docs/guides/storage/image-transformations#nextjs-loader
export default function supabaseLoader({ src, width, quality }) {
  const url = new URL(`https://example.com${src}`)
  url.searchParams.set('width', width.toString())


url.searchParams.set('width', width.toString())
  url.searchParams.set('quality', (quality || 75).toString())
  return url.href
}


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:
next.config.js module.exports = {
  async headers() {
    return [
      {
        source: '/about',
        headers: [
          {
            key: 'x-custom-header',
            value: 'my custom header value',
          },
          {
            key: 'x-another-custom-header',
            value: 'my other custom header value',
          },
        ],
      },
    ]
  },
}
headers is an async function that expects an array to be returned holding objects with source and headers properties:
source is the incoming request path pattern.
headers is an array of response header objects, with key and value properties.


headers is an array of response header objects, with key and value properties.
basePath: false or undefined - if false the basePath won't be included when matching, can be used for external rewrites only.
locale: false or undefined - whether the locale should not be included when matching.
has is an array of has objects with the type, key and value properties.
missing is an array of missing objects with the type, key and value properties.
Headers are checked before the filesystem which includes pages and /public files.
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 world due to the last header value set being world.
next.config.js module.exports = {
  async headers() {
    return [
      {
        source: '/:path*',


return [
      {
        source: '/:path*',
        headers: [
          {
            key: 'x-hello',
            value: 'there',
          },
        ],
      },
      {
        source: '/hello',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
    ]
  },
}
Path Matching
Path matches are allowed, for example /blog/:slug will match /blog/hello-world (no nested paths):
next.config.js module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug',
        headers: [
          {
            key: 'x-slug',
            value: ':slug', // Matched parameters can be used in the value
          },
          {


},
          {
            key: 'x-slug-:slug', // Matched parameters can be used in the key
            value: 'my other custom header value',
          },
        ],
      },
    ]
  },
}
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:
next.config.js module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:slug*',
        headers: [
          {
            key: 'x-slug',
            value: ':slug*', // Matched parameters can be used in the value
          },
          {
            key: 'x-slug-:slug*', // Matched parameters can be used in the key
            value: 'my other custom header value',
          },


value: 'my other custom header value',
          },
        ],
      },
    ]
  },
}
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:
next.config.js module.exports = {
  async headers() {
    return [
      {
        source: '/blog/:post(\\d{1,})',
        headers: [
          {
            key: 'x-post',
            value: ':post',
          },
        ],
      },
    ]
  },
}
The following characters (, ), {, }, :, *, +, ? are used for regex path matching, so when used in the source as non-special values they must be escaped by adding \\ before them:


next.config.js module.exports = {
  async headers() {
    return [
      {
        // this will match `/english(default)/something` being requested
        source: '/english\\(default\\)/:slug',
        headers: [
          {
            key: 'x-header',
            value: 'value',
          },
        ],
      },
    ]
  },
}
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 missing items must not match for the header to be applied.
has and missing items can have the following fields:
type: String - must be either header, cookie, host, or query.
key: String - the key from the selected type to match against.


key: String - the key from the selected type to match against.
value: String or undefined - the value to check for, if undefined any value will match. A regex like string can be used to capture a specific part of the value, e.g. if the value first-(?<paramName>.*) is used for first-second then second will be usable in the destination with :paramName.
next.config.js module.exports = {
  async headers() {
    return [
      // if the header `x-add-header` is present,
      // the `x-another-header` header will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-add-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],


value: 'hello',
          },
        ],
      },
      // if the header `x-no-header` is not present,
      // the `x-another-header` header will be applied
      {
        source: '/:path*',
        missing: [
          {
            type: 'header',
            key: 'x-no-header',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: 'hello',
          },
        ],
      },
      // if the source, query, and cookie are matched,
      // the `x-authorized` header will be applied
      {
        source: '/specific/:path*',
        has: [
          {
            type: 'query',
            key: 'page',
            // the page value will not be available in the


key: 'page',
            // the page value will not be available in the
            // header key/values since value is provided and
            // doesn't use a named capture group e.g. (?<page>home)
            value: 'home',
          },
          {
            type: 'cookie',
            key: 'authorized',
            value: 'true',
          },
        ],
        headers: [
          {
            key: 'x-authorized',
            value: ':authorized',
          },
        ],
      },
      // if the header `x-authorized` is present and
      // contains a matching value, the `x-another-header` will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'header',
            key: 'x-authorized',


{
            type: 'header',
            key: 'x-authorized',
            value: '(?<authorized>yes|true)',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
      // if the host is `example.com`,
      // this header will be applied
      {
        source: '/:path*',
        has: [
          {
            type: 'host',
            value: 'example.com',
          },
        ],
        headers: [
          {
            key: 'x-another-header',
            value: ':authorized',
          },
        ],
      },
    ]
  },
}
Headers with basePath support


],
      },
    ]
  },
}
Headers with basePath support
When leveraging basePath support with headers each source is automatically prefixed with the basePath unless you add basePath: false to the header:
next.config.js module.exports = {
  basePath: '/docs',

  async headers() {
    return [
      {
        source: '/with-basePath', // becomes /docs/with-basePath
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        source: '/without-basePath', // is not modified since basePath: false is set
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
        basePath: false,
      },
    ]
  },
}
Headers with i18n support


},
    ]
  },
}
Headers with i18n support
When leveraging i18n support with headers each source is automatically prefixed to handle the configured locales unless you add locale: false to the header. If locale: false is used you must prefix the source with a locale for it to be matched correctly.
next.config.js module.exports = {
  i18n: {
    locales: ['en', 'fr', 'de'],
    defaultLocale: 'en',
  },

  async headers() {
    return [
      {
        source: '/with-locale', // automatically handles all locales
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // does not handle locales automatically since locale: false is set
        source: '/nl/with-locale-manual',


source: '/nl/with-locale-manual',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // this matches '/' since `en` is the defaultLocale
        source: '/en',
        locale: false,
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },
      {
        // this gets converted to /(en|fr|de)/(.*) so will not match the top-level
        // `/` or `/fr` routes like /:path* would
        source: '/(.*)',
        headers: [
          {
            key: 'x-hello',
            value: 'world',
          },
        ],
      },


value: 'world',
          },
        ],
      },
    ]
  },
}
Cache-Control
You can set the Cache-Control header in your Next.js API Routes by using the res.setHeader method:
pages/api/user.js export default function handler(req, res) {
  res.setHeader('Cache-Control', 's-maxage=86400')
  res.status(200).json({ name: 'John Doe' })
}
You cannot set Cache-Control headers in next.config.js file as these will be overwritten in production to ensure that API Routes and static assets are cached effectively.
If you need to revalidate the cache of a page that has been statically generated, you can do so by setting the revalidate prop in the page's getStaticProps function.
Options
X-DNS-Prefetch-Control


Options
X-DNS-Prefetch-Control
This header controls DNS prefetching, allowing browsers to proactively perform domain name resolution on external links, images, CSS, JavaScript, and more. This prefetching is performed in the background, so the DNS is more likely to be resolved by the time the referenced items are needed. This reduces latency when the user clicks a link.
 {
  key: 'X-DNS-Prefetch-Control',
  value: 'on'
}
Strict-Transport-Security
This header informs browsers it should only be accessed using HTTPS, instead of using HTTP. Using the configuration below, all present and future subdomains will use HTTPS for a max-age of 2 years. This blocks access to pages or subdomains that can only be served over HTTP.
If you're deploying to Vercel, this header is not necessary as it's automatically added to all deployments unless you declare headers in your next.config.js.
 {


{
  key: 'Strict-Transport-Security',
  value: 'max-age=63072000; includeSubDomains; preload'
}
X-XSS-Protection
This header stops pages from loading when they detect reflected cross-site scripting (XSS) attacks. Although this protection is not necessary when sites implement a strong Content-Security-Policy disabling the use of inline JavaScript ('unsafe-inline'), it can still provide protection for older web browsers that don't support CSP.
 {
  key: 'X-XSS-Protection',
  value: '1; mode=block'
}
X-Frame-Options
This header indicates whether the site should be allowed to be displayed within an iframe. This can prevent against clickjacking attacks. This header has been superseded by CSP's frame-ancestors option, which has better support in modern browsers.
 {
  key: 'X-Frame-Options',


{
  key: 'X-Frame-Options',
  value: 'SAMEORIGIN'
}
Permissions-Policy
This header allows you to control which features and APIs can be used in the browser. It was previously named Feature-Policy. You can view the full list of permission options here.
 {
  key: 'Permissions-Policy',
  value: 'camera=(), microphone=(), geolocation=(), browsing-topics=()'
}
X-Content-Type-Options
This header prevents the browser from attempting to guess the type of content if the Content-Type header is not explicitly set. This can prevent XSS exploits for websites that allow users to upload and share files. For example, a user trying to download an image, but having it treated as a different Content-Type like an executable, which could be malicious. This header also applies to downloading browser extensions. The only valid value for this header is nosniff.
 {


{
  key: 'X-Content-Type-Options',
  value: 'nosniff'
}
Referrer-Policy
This header controls how much information the browser includes when navigating from the current website (origin) to another. You can read about the different options here.
 {
  key: 'Referrer-Policy',
  value: 'origin-when-cross-origin'
}
Content-Security-Policy
This header helps prevent cross-site scripting (XSS), clickjacking and other code injection attacks. Content Security Policy (CSP) can specify allowed origins for content including scripts, stylesheets, images, fonts, objects, media (audio, video), iframes, and more.
You can read about the many different CSP options here.
You can add Content Security Policy directives using a template string.
 // Before defining your Security Headers
// add Content Security Policy directives using a template string.


// add Content Security Policy directives using a template string.

const ContentSecurityPolicy = `
  default-src 'self';
  script-src 'self';
  child-src example.com;
  style-src 'self' example.com;
  font-src 'self';
`
When a directive uses a keyword such as self, wrap it in single quotes ''.
In the header's value, replace the new line with a space.
 {
  key: 'Content-Security-Policy',
  value: ContentSecurityPolicy.replace(/\s{2,}/g, ' ').trim()
}
Version History
VersionChangesv13.3.0missing added.v10.2.0has added.v9.5.0Headers added.


reactStrictMode
Good to know: Since Next.js 13.4, 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 reactStrictMode: false.
Suggested: We strongly suggest you enable Strict Mode in your Next.js application to better prepare your application for the future of React.
React's Strict Mode is a development mode only feature for highlighting potential problems in an application. It helps to identify unsafe lifecycles, legacy API usage, and a number of other features.
The Next.js runtime is Strict Mode-compliant. To opt-in to Strict Mode, configure the following option in your next.config.js:
next.config.js module.exports = {
  reactStrictMode: true,
}


next.config.js module.exports = {
  reactStrictMode: true,
}
If you or your team are not ready to use Strict Mode in your entire application, that's OK! You can incrementally migrate on a page-by-page basis using <React.StrictMode>.


turbo (Experimental)
Warning: These features are experimental and will only work with next --turbo.
webpack loaders
Currently, Turbopack supports a subset of webpack's loader API, allowing you to use some webpack loaders to transform code in Turbopack.
To configure loaders, add the names of the loaders you've installed and any options in next.config.js, mapping file extensions to a list of loaders:
next.config.js module.exports = {
  experimental: {
    turbo: {
      loaders: {
        // Option format
        '.md': [
          {
            loader: '@mdx-js/loader',
            options: {
              format: 'md',
            },
          },
        ],
        // Option-less format
        '.mdx': ['@mdx-js/loader'],
      },
    },
  },
}


},
    },
  },
}
Then, given the above configuration, you can use transformed code from your app:
 import MyDoc from './my-doc.mdx'

export default function Home() {
  return <MyDoc />
}
Resolve Alias
Through next.config.js, Turbopack can be configured to modify module resolution through aliases, similar to webpack's resolve.alias configuration.
To configure resolve aliases, map imported patterns to their new destination in next.config.js:
next.config.js module.exports = {
  experimental: {
    turbo: {
      resolveAlias: {
        underscore: 'lodash',
        mocha: { browser: 'mocha/browser-entry.js' },
      },
    },
  },
}
This aliases imports of the underscore package to the lodash package. In other words, import underscore from 'underscore' will load the lodash module instead of underscore.


Turbopack also supports conditional aliasing through this field, similar to Node.js's conditional exports. At the moment only the browser condition is supported. In the case above, imports of the mocha module will be aliased to mocha/browser-entry.js when Turbopack targets browser environments.
For more information and guidance for how to migrate your app to Turbopack from webpack, see Turbopack's documentation on webpack compatibility.


Custom Webpack Config
Good to know: changes to webpack config are not covered by semver so proceed at your own risk
Before continuing to add custom webpack configuration to your application make sure Next.js doesn't already support your use-case:
CSS imports
CSS modules
Sass/SCSS imports
Sass/SCSS modules
preact
Some commonly asked for features are available as plugins:
@next/mdx
@next/bundle-analyzer
In order to extend our usage of webpack, you can define a function that extends its config inside next.config.js, like so:
next.config.js module.exports = {
  webpack: (
    config,
    { buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
  ) => {
    // Important: return the modified config
    return config
  },
}


// Important: return the modified config
    return config
  },
}
The webpack function is executed twice, once for the server and once for the client. This allows you to distinguish between client and server configuration using the isServer property.
The second argument to the webpack function is an object with the following properties:
buildId: String - The build id, used as a unique identifier between builds
dev: Boolean - Indicates if the compilation will be done in development
isServer: Boolean - It's true for server-side compilation, and false for client-side compilation
nextRuntime: String | undefined - The target runtime for server-side compilation; either "edge" or "nodejs", it's undefined for client-side compilation.
defaultLoaders: Object - Default loaders used internally by Next.js:
babel: Object - Default babel-loader configuration
Example usage of defaultLoaders.babel:
 // Example config for adding a loader that depends on babel-loader


// Example config for adding a loader that depends on babel-loader
// This source was taken from the @next/mdx plugin source:
// https://github.com/vercel/next.js/tree/canary/packages/next-mdx
module.exports = {
  webpack: (config, options) => {
    config.module.rules.push({
      test: /\.mdx/,
      use: [
        options.defaultLoaders.babel,
        {
          loader: '@mdx-js/loader',
          options: pluginOptions.options,
        },
      ],
    })

    return config
  },
}
nextRuntime
Notice that isServer is true when nextRuntime is "edge" or "nodejs", nextRuntime "edge" is currently for middleware and Server Components in edge runtime only.


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:
next.config.js module.exports = {
  distDir: 'build',
}
Now if you run next build Next.js will use build instead of the default .next folder.
distDir should not leave your project directory. For example, ../build is an invalid directory.


typescript
Next.js fails your production build (next build) when TypeScript errors are present in your project.
If you'd like Next.js to dangerously produce production code even when your application has errors, you can disable the built-in type checking step.
If disabled, be sure you are running type checks as part of your build or deploy process, otherwise this can be very dangerous.
Open next.config.js and enable the ignoreBuildErrors option in the typescript config:
next.config.js module.exports = {
  typescript: {
    // !! WARN !!
    // Dangerously allow production builds to successfully complete even if
    // your project has type errors.
    // !! WARN !!
    ignoreBuildErrors: true,
  },
}


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 configuration flag.
Next.js provides a configuration flag you can use to enable browser source map generation during the production build:
next.config.js module.exports = {
  productionBrowserSourceMaps: true,
}
When the productionBrowserSourceMaps option is enabled, the source maps will be output in the same directory as the JavaScript files. Next.js will automatically serve these files when requested.
Adding source maps can increase next build time
Increases memory usage during next build


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 opposite way, where urls without trailing slashes are redirected to their counterparts with trailing slashes.
Open next.config.js and add the trailingSlash config:
next.config.js module.exports = {
  trailingSlash: true,
}
With this option set, urls like /about will redirect to /about/.
Version History
VersionChangesv9.5.0trailingSlash added.


urlImports
URL imports are an experimental feature that allows you to import modules directly from external servers (instead of from the local disk).
Warning: This feature is experimental. Only use domains that you trust to download and execute on your machine. Please exercise
discretion, and caution until the feature is flagged as stable.
To opt-in, add the allowed URL prefixes inside next.config.js:
next.config.js module.exports = {
  experimental: {
    urlImports: ['https://example.com/assets/', 'https://cdn.skypack.dev'],
  },
}
Then, you can import modules directly from URLs:
 import { a, b, c } from 'https://example.com/assets/some/module.js'
URL Imports can be used everywhere normal package imports can be used.
Security Model


URL Imports can be used everywhere normal package imports can be used.
Security Model
This feature is being designed with security as the top priority. To start, we added an experimental flag forcing you to explicitly allow the domains you accept URL imports from. We're working to take this further by limiting URL imports to execute in the browser sandbox using the Edge Runtime.
Lockfile
When using URL imports, Next.js will create a next.lock directory containing a lockfile and fetched assets.
This directory must be committed to Git, not ignored by .gitignore.
When running next dev, Next.js will download and add all newly discovered URL Imports to your lockfile
When running next build, Next.js will use only the lockfile to build the application for production
Typically, no network requests are needed and any outdated lockfile will cause the build to fail.
One exception is resources that respond with Cache-Control: no-cache.


One exception is resources that respond with Cache-Control: no-cache.
These resources will have a no-cache entry in the lockfile and will always be fetched from the network on each build.
Examples
Skypack
 import confetti from 'https://cdn.skypack.dev/canvas-confetti'
import { useEffect } from 'react'

export default () => {
  useEffect(() => {
    confetti()
  })
  return
Hello

}
Static Image Imports
 import Image from 'next/image'
import logo from 'https://example.com/assets/logo.png'

export default () => (

    <Image src={logo} placeholder="blur" />

)
URLs in CSS
 .className {
  background: url('https://example.com/assets/hero.jpg');
}
Asset Imports


background: url('https://example.com/assets/hero.jpg');
}
Asset Imports
 const logo = new URL('https://example.com/assets/file.txt', import.meta.url)

console.log(logo.pathname)

// prints "/_next/static/media/file.a9727b5d.txt"


mdxRsFor use with @next/mdx. Compile MDX files using the new Rust compiler.
next.config.js const withMDX = require('@next/mdx')()

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

module.exports = withMDX(nextConfig)


devIndicators
When you edit your code, and Next.js is compiling the application, a compilation indicator appears in the bottom right corner of the page.
Good to know: This indicator is only present in development mode and will not appear when building and running the app in production mode.
In some cases this indicator can be misplaced on your page, for example, when conflicting with a chat launcher. To change its position, open next.config.js and set the buildActivityPosition in the devIndicators object to bottom-right (default), bottom-left, top-right or top-left:next.config.js module.exports = {
  devIndicators: {
    buildActivityPosition: 'bottom-right',
  },
}In some cases this indicator might not be useful for you. To remove it, open next.config.js and disable the buildActivity config in devIndicators object:next.config.js module.exports = {
  devIndicators: {
    buildActivity: false,


devIndicators: {
    buildActivity: false,
  },
}


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:
next.config.js module.exports = {
  poweredByHeader: false,
}


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 onDemandEntries config:
next.config.js 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 without being disposed
    pagesBufferLength: 2,
  },
}


<Script>
This API reference will help you understand how to use props available for the Script Component. For features and usage, please see the Optimizing Scripts page.
app/dashboard/page.tsx 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:
PropExampleTypeRequiredsrcsrc="http://example.com/script"StringRequired unless inline script is usedstrategystrategy="lazyOnload"String-onLoadonLoad={onLoadFunc}Function-onReadyonReady={onReadyFunc}Function-onErroronError={onErrorFunc}Function-
Required Props
The <Script /> component requires the following properties.
src


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.
afterInteractive: (default) Load early but after some hydration on the page occurs.
lazyOnload: Load during browser idle time.
worker: (experimental) Load in a web worker.
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 before any hydration occurs on the page.


Scripts denoted with this strategy are preloaded and fetched before any first-party code, but their execution does not block page hydration from occurring.
beforeInteractive scripts must be placed inside the root layout (app/layout.tsx) and are designed to load scripts that are needed by the entire site (i.e. the script will load when any page in the application has been loaded server-side).
This strategy should only be used for critical scripts that need to be fetched before any part of the page becomes interactive.
app/layout.tsx import Script from 'next/script'

export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
      <Script
        src="https://example.com/script.js"
        strategy="beforeInteractive"
      />
    </html>
  )
}


strategy="beforeInteractive"
      />
    </html>
  )
}
Good to know: Scripts with beforeInteractive will always be injected inside the head of the HTML document regardless of where it's placed in the component.
Some examples of scripts that should be loaded as soon as possible with beforeInteractive include:
Bot detectors
Cookie consent managers
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 component and should be used for any script that needs to load as soon as possible but not before any first-party Next.js code.
afterInteractive scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.
app/page.js import Script from 'next/script'

export default function Page() {
  return (


export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="afterInteractive" />
    </>
  )
}
Some examples of scripts that are good candidates for afterInteractive include:
Tag managers
Analytics
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 used for any background or low priority scripts that do not need to load early.
lazyOnload scripts can be placed inside of any page or layout and will only load and execute when that page (or group of pages) is opened in the browser.
app/page.js import Script from 'next/script'

export default function Page() {
  return (
    <>


export default function Page() {
  return (
    <>
      <Script src="https://example.com/script.js" strategy="lazyOnload" />
    </>
  )
}
Examples of scripts that do not need to load immediately and can be fetched with lazyOnload include:
Chat support plugins
Social media widgets
worker
Warning: The worker strategy is not yet stable and does not yet work with the app directory. Use with caution.
Scripts that use the worker strategy are off-loaded to a web worker in order to free up the main thread and ensure that only critical, first-party resources are processed on it. While this strategy can be used for any script, it is an advanced use case that is not guaranteed to support all third-party scripts.
To use worker as a strategy, the nextScriptWorkers flag must be enabled in next.config.js:
next.config.js module.exports = {
  experimental: {


next.config.js module.exports = {
  experimental: {
    nextScriptWorkers: true,
  },
}
worker scripts can only currently be used in the pages/ directory:
pages/home.tsx 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 instead.
Some third-party scripts require users to run JavaScript code once after the script has finished loading in order to instantiate content or call a function. If you are loading a script with either afterInteractive or lazyOnload as a loading strategy, you can execute code after it has loaded using the onLoad property.


Here's an example of executing a lodash method only after the library has been loaded.
app/page.tsx 'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js"
        onLoad={() => {
          console.log(_.sample([1, 2, 3, 4]))
        }}
      />
    </>
  )
}
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 finished loading and every time the component is mounted (after a route navigation for example). You can execute code after the script's load event when it first loads and then after every subsequent component re-mount using the onReady property.
Here's an example of how to re-instantiate a Google Maps JS embed every time the component is mounted:
app/page.tsx 'use client'

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

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

  return (
    <>


onReady={() => {
          new google.maps.Map(mapRef.current, {
            center: { lat: -34.397, lng: 150.644 },
            zoom: 8,
          })
        }}
      />
    </>
  )
}
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 helpful to catch when a script fails to load. These errors can be handled with the onError property:
app/page.tsx 'use client'

import Script from 'next/script'

export default function Page() {
  return (
    <>
      <Script
        src="https://example.com/script.js"
        onError={(e: Error) => {
          console.error('Script failed to load', e)
        }}
      />


console.error('Script failed to load', e)
        }}
      />
    </>
  )
}
Version History
VersionChangesv13.0.0beforeInteractive and afterInteractive is modified to support app.v12.2.4onReady prop added.v12.2.2Allow next/script with beforeInteractive to be placed in _document.v11.0.0next/script introduced.


<Image>
Examples
Image Component
This API reference will help you understand how to use props and configuration options available for the Image Component. For features and usage, please see the Image Component page.
app/page.js import Image from 'next/image'

export default function Page() {
  return (
    <Image
      src="/profile.png"
      width={500}
      height={500}
      alt="Picture of the author"
    />
  )
}
Props
Here's a summary of the props available for the Image Component:


}
Props
Here's a summary of the props available for the Image Component:
PropExampleTypeRequiredsrcsrc="/profile.png"StringYeswidthwidth={500}Integer (px)Yesheightheight={500}Integer (px)Yesaltalt="Picture of the author"StringYesloaderloader={imageLoader}Function-fillfill={true}Boolean-sizessizes="(max-width: 768px) 100vw"String-qualityquality={80}Integer (1-100)-prioritypriority={true}Boolean-placeholderplaceholder="blur"String-stylestyle={{objectFit: "contain"}}Object-onLoadingCompleteonLoadingComplete={img => done())}Function-onLoadonLoad={event => done())}Function-onErroronError(event => fail()}Function-loadingloading="lazy"String-blurDataURLblurDataURL="data:image/jpeg..."String-
Required Props
The Image Component requires the following properties: src, width, height, and alt.


The Image Component requires the following properties: src, width, height, and alt.
app/page.js import Image from 'next/image'

export default function Page() {
  return (
    <div>
      <Image
        src="/profile.png"
        width={500}
        height={500}
        alt="Picture of the author"
      />
    </div>
  )
}
src
Must be one of the following:
A statically imported image file
A path string. This can be either an absolute external URL, or an internal path depending on the loader prop.
When using an external URL, you must add it to remotePatterns in next.config.js.
width
The width property represents the rendered width in pixels, so it will affect how large the image appears.
Required, except for statically imported images or images with the fill property.
height


Required, except for statically imported images or images with the fill property.
height
The height property represents the rendered height in pixels, so it will affect how large the image appears.
Required, except for statically imported images or images with the fill property.
alt
The alt property is used to describe the image for screen readers and search engines. It is also the fallback text if images have been disabled or an error occurs while loading the image.
It should contain text that could replace the image without changing the meaning of the page. It is not meant to supplement the image and should not repeat information that is already provided in the captions above or below the image.
If the image is purely decorative or not intended for the user, the alt property should be an empty string (alt="").
Learn more
Optional Props


Learn more
Optional Props
The <Image /> component accepts a number of additional properties beyond those which are required. This section describes the most commonly-used properties of the Image component. Find details about more rarely-used properties in the Advanced Props section.
loader
A custom function used to resolve image URLs.
A loader is a function returning a URL string for the image, given the following parameters:
src
width
quality
Here is an example of using a custom loader:
 'use client'

import Image from 'next/image'

const imageLoader = ({ src, width, quality }) => {
  return `https://example.com/${src}?w=${width}&q=${quality || 75}`
}

export default function Page() {
  return (
    <Image
      loader={imageLoader}
      src="me.png"
      alt="Picture of the author"
      width={500}


alt="Picture of the author"
      width={500}
      height={500}
    />
  )
}
Good to know: Using props like loader, which accept a function, require using Client Components to serialize the provided function.
Alternatively, you can use the loaderFile configuration in next.config.js to configure every instance of next/image in your application, without passing a prop.
fill
 fill={true} // {true} | {false}
A boolean that causes the image to fill the parent element instead of setting width and height.
The parent element must assign position: "relative", position: "fixed", or position: "absolute" style.
By default, the img element will automatically be assigned the position: "absolute" style.


By default, the img element will automatically be assigned the position: "absolute" style.
The default image fit behavior will stretch the image to fit the container. You may prefer to set object-fit: "contain" for an image which is letterboxed to fit the container and preserve aspect ratio.
Alternatively, object-fit: "cover" will cause the image to fill the entire container and be cropped to preserve aspect ratio. For this to look correct, the overflow: "hidden" style should be assigned to the parent element.
For more information, see also:
position
object-fit
object-position
sizes
A string that provides information about how wide the image will be at different breakpoints. The value of sizes will greatly affect performance for images using fill or which are styled to have a responsive size.
The sizes property serves two important purposes related to image performance:


The sizes property serves two important purposes related to image performance:
First, the value of sizes is used by the browser to determine which size of the image to download, from next/image's automatically-generated source set. When the browser chooses, it does not yet know the size of the image on the page, so it selects an image that is the same size or larger than the viewport. The sizes property allows you to tell the browser that the image will actually be smaller than full screen. If you don't specify a sizes value in an image with the fill property, a default value of 100vw (full screen width) is used.


Second, the sizes property configures how next/image automatically generates an image source set. If no sizes value is present, a small source set is generated, suitable for a fixed-size image. If sizes is defined, a large source set is generated, suitable for a responsive image. If the sizes property includes sizes such as 50vw, which represent a percentage of the viewport width, then the source set is trimmed to not include any values which are too small to ever be necessary.
For example, if you know your styling will cause an image to be full-width on mobile devices, in a 2-column layout on tablets, and a 3-column layout on desktop displays, you should include a sizes property such as the following:
 import Image from 'next/image'

export default function Page() {
  return (
    <div className="grid-element">
      <Image
        fill
        src="/example.png"


<Image
        fill
        src="/example.png"
        sizes="(max-width: 768px) 100vw, (max-width: 1200px) 50vw, 33vw"
      />
    </div>
  )
}
This example sizes could have a dramatic effect on performance metrics. Without the 33vw sizes, the image selected from the server would be 3 times as wide as it needs to be. Because file size is proportional to the square of the width, without sizes the user would download an image that's 9 times larger than necessary.
Learn more about srcset and sizes:
web.dev
mdn
quality
 quality={75} // {number 1-100}
The quality of the optimized image, an integer between 1 and 100, where 100 is the best quality and therefore largest file size. Defaults to 75.
priority


priority
 priority={false} // {false} | {true}
When true, the image will be considered high priority and
preload. Lazy loading is automatically disabled for images using priority.
You should use the priority property on any image detected as the Largest Contentful Paint (LCP) element. It may be appropriate to have multiple priority images, as different images may be the LCP element for different viewport sizes.
Should only be used when the image is visible above the fold. Defaults to false.
placeholder
 placeholder = 'empty' // {empty} | {blur}
A placeholder to use while the image is loading. Possible values are blur or empty. Defaults to empty.
When blur, the blurDataURL property will be used as the placeholder. If src is an object from a static import and the imported image is .jpg, .png, .webp, or .avif, then blurDataURL will be automatically populated.


For dynamic images, you must provide the blurDataURL property. Solutions such as Plaiceholder can help with base64 generation.
When empty, there will be no placeholder while the image is loading, only empty space.
Try it out:
Demo the blur placeholder
Demo the shimmer effect with blurDataURL prop
Demo the color effect with blurDataURL prop
Advanced Props
In some cases, you may need more advanced usage. The <Image /> component optionally accepts the following advanced properties.
style
Allows passing CSS styles to the underlying image element.
components/ProfileImage.js const imageStyle = {
  borderRadius: '50%',
  border: '1px solid #fff',
}

export default function ProfileImage() {
  return <Image src="..." style={imageStyle} />
}


return <Image src="..." style={imageStyle} />
}
Remember that the required width and height props can interact with your styling. If you use styling to modify an image's width, you should also style its height to auto to preserve its intrinsic aspect ratio, or your image will be distorted.
onLoadingComplete
 'use client'

<Image onLoadingComplete={(img) => console.log(img.naturalWidth)} />
A callback function that is invoked once the image is completely loaded and the placeholder has been removed.
The callback function will be called with one argument, a reference to the underlying <img> element.
Good to know: Using props like onLoadingComplete, which accept a function, require using Client Components to serialize the provided function.
onLoad
 <Image onLoad={(e) => console.log(e.target.naturalWidth)} />
A callback function that is invoked when the image is loaded.