gavmac00/nextjs-app-docs huggingface dataset:
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 <h1>The value of customKey is: {process.env.customKey}</h1>
}
 
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 <h1>The value of customKey is: {process.env.customKey}</h1>
Will end up being:
 return <h1>The value of customKey is: {'my-value'}</h1>