rewrites header, cookie, query matching examples
Examples of rewrites with header, cookie, and query matching using `has` and `missing`:
```js
module.exports = {
rewrites() {
return [
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
destination: '/:path*/home',
},
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
destination: '/home?authorized=:authorized',
},
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
```
rewrites external URL example
Example of rewrites to external URLs:
```js
module.exports = {
rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug',
},
]
},
}
```
rewrites trailingSlash example
Example of rewrites with trailingSlash configuration:
```js
module.exports = {
trailingSlash: true,
rewrites() {
return [
{
source: '/blog/',
destination: 'https://example.com/blog/',
},
{
source: '/blog/:path*/',
destination: 'https://example.com/blog/:path*/',
},
]
},
}
```
rewrites incremental adoption example
Example of incremental adoption of Next.js using rewrites:
```js
module.exports = {
rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
},
}
```
rewrites basePath support example
Example of rewrites with basePath support:
```js
module.exports = {
basePath: '/docs',
rewrites() {
return [
{
source: '/with-basePath',
destination: '/another',
},
{
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
},
]
},
}
```
The first rewrite automatically becomes `/docs/with-basePath` → `/docs/another`. The second does not add `/docs` since `basePath: false` is set.
rewrites parameter used in destination example
Example of rewrite where a parameter is used in the destination:
```js
module.exports = {
rewrites() {
return [
{
source: '/docs/:path*',
destination: '/:path*',
},
]
},
}
```
The `:path` parameter is used in the destination so will not be automatically passed in the query.
rewrites manual query parameter example
Example of manually passing parameters in the query when one is already used in the destination:
```js
module.exports = {
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, but we can manually add it as shown.
serverExternalPackages config option
The serverExternalPackages configuration option in next.config.js allows you to opt-out specific dependencies from Server Components bundling and use native Node.js require instead. This is useful for dependencies that use Node.js specific features. It takes an array of package names as strings. Example: const nextConfig = { serverExternalPackages: ['@acme/ui'] };
Dependencies bundled in Server Components by default
Dependencies used inside Server Components and Route Handlers are automatically bundled by Next.js by default.
Next.js automatically opt-ed out packages
Next.js includes a built-in list of popular packages that are automatically opted out from Server Components bundling and use native Node.js require. These packages include: @alinea/generated, @appsignal/nodejs, @aws-sdk/client-s3, @aws-sdk/s3-presigned-post, @blockfrost/blockfrost-js, @highlight-run/node, @huggingface/transformers, @jpg-store/lucid-cardano, @libsql/client, @mikro-orm/core, @mikro-orm/knex, @node-rs/argon2, @node-rs/bcrypt, @prisma/client, @react-pdf/renderer, @sentry/profiling-node, @sparticuz/chromium, @sparticuz/chromium-min, @statsig/statsig-node-core, @swc/core, @xenova/transformers, @zenstackhq/runtime, argon2, autoprefixer, aws-crt, bcrypt, better-sqlite3, canvas, chromadb-default-embed, config, cpu-features, cypress, dd-trace, eslint, express, firebase-admin, htmlrewriter, import-in-the-middle, isolated-vm, jest, jsdom, keyv, libsql, mdx-bundler, mongodb, mongoose, newrelic, next-mdx-remote, next-seo, node-cron, node-pty, node-web-audio-api, onnxruntime-node, oslo, pg, pino, pino-pretty, pino-roll, playwright, playwright-core, postcss, prettier, prisma, puppeteer-core, puppeteer, ravendb, require-in-the-middle, rimraf, sharp, shiki, sqlite3, thread-stream, ts-morph, ts-node, typescript, vscode-oniguruma, webpack, websocket, zeromq.
serverExternalPackages version history
In v15.0.0, serverExternalPackages was moved from experimental to stable status. It was also renamed from the previous name serverComponentsExternalPackages.
turbopack config option in next.config.ts
The turbopack option can be defined in next.config.ts using TypeScript syntax. The configuration accepts a NextConfig type: const nextConfig: NextConfig = { turbopack: { // ... }, }
turbopack config option in next.config.js
The turbopack option can be defined in next.config.js using JavaScript syntax. The configuration object has type NextConfig: const nextConfig = { turbopack: { // ... }, }; module.exports = nextConfig;
maxChunkCountPerGroup turbopackChunking option
The maxChunkCountPerGroup option (default 40) in turbopackChunking sets the maximum number of chunks Turbopack will emit per chunk group, such as a route or dynamic import. Lowering this number leads to more aggressive merging and fewer network requests per page. Raising it produces smaller chunks and increases cache hit likelihood when navigating.
maxMergeChunkSize turbopackChunking option
The maxMergeChunkSize option (default 200000 bytes) in turbopackChunking sets a ceiling on chunk size: Turbopack never merges a chunk larger than this size with other chunks. This prevents code in large chunks from being duplicated across multiple large output chunks. Size is in uncompressed, unminified code bytes.
priorityRoutes turbopackChunking heuristic
The priorityRoutes option in turbopackChunking is an array of RegExp patterns for routes that are often the first page a visitor lands on, such as the homepage. Their client-side bundles are merged more eagerly to reduce the single-route request cost, at the expense of extra requests when navigating to other pages.
requestCost turbopackChunking heuristic
The requestCost option (default 200000 bytes of uncompressed, unminified code) in turbopackChunking represents the estimated cost of an additional network request. Larger values bias Turbopack toward fewer, larger chunks and fewer overall requests.
turbopackChunking Pages Router default configuration
The default turbopackChunking configuration for the Pages Router is: minChunkSize: 50000, maxChunkCountPerGroup: 40, maxMergeChunkSize: 200000.
turbopackChunking size measurement units
All size values in turbopackChunking configuration (minChunkSize, maxMergeChunkSize, minComponentChunkSize, requestCost) are measured in bytes of uncompressed, unminified code, which is roughly 5x the size of compressed, minified output.
turbopackChunking experimental config
The experimental.turbopackChunking config option in next.config.js or next.config.ts allows you to configure how Turbopack splits client-side JavaScript into chunks in production. It lets you change assumptions about user behaviour, tweak size thresholds, and (in App Router only) enable component chunks generation.
minChunkSize turbopackChunking option
The minChunkSize option (default 50000 bytes) in turbopackChunking controls the minimum size of individual chunks. Turbopack avoids creating chunks smaller than this size by merging them into larger ones. Raising this number produces fewer, larger chunks; lowering it produces more, smaller chunks. Size is in uncompressed, unminified code bytes.
priorityBoost turbopackChunking heuristic
The priorityBoost option (default 1.5) in turbopackChunking is a multiplier applied to the single-request probability of priorityRoutes routes. Higher values cause those routes' bundles to be merged more aggressively.
turbopackChunking trade-off between initial load and navigation
When merging chunks in turbopackChunking configuration, the trade-off is improved initial page load performance at the cost of navigation performance. Each additional network request is costly, but smaller chunks are more likely to be reusable across pages.
generateComponentChunks App Router only
The generateComponentChunks option (default false) is only available in the App Router. When enabled, each merged production chunk also emits its constituent component chunks alongside it, allowing the browser runtime to fetch individual component chunks and avoid re-downloading JavaScript the browser already has when navigating.
minComponentChunkSize turbopackChunking option
The minComponentChunkSize option (default 20000 bytes) in turbopackChunking specifies the minimum size for component chunks. Component chunks smaller than this size are folded into a single component instead of being emitted separately, to avoid producing many tiny chunks. This option is only available in the App Router.
firstPageLoadPriority turbopackChunking heuristic
The firstPageLoadPriority option in turbopackChunking is a number between 0 and 1 that controls how heavily the chunker weighs the benefit of merging chunks for a single page load. Higher values merge chunks more eagerly. If you don't have a better value, your site's bounce rate is a good approximation.
next.config.js webpack example for stats generation
module.exports = {
webpack(config) {
config.profile = true
return config
},
}
App Shell caching with session data
Routes that read cookies() or headers() produce an App Shell that includes session data. The framework auto-detects this and caches the shell per session on the client.
partialPrefetching version history
partialPrefetching was introduced in version 16.3.0. It requires cacheComponents to be enabled.
Per-segment prefetch override
A segment that exports an explicit prefetch value overrides the app-level partialPrefetching default for that route.
Link prefetch={true} with partialPrefetching
A link can ask for more than the App Shell by using <Link prefetch={true}>. This prefetch resolves URL data like params, searchParams, and the full URL, and the cached content behind it.
partialPrefetching configuration example
In next.config.ts: import type { NextConfig } from 'next'; const nextConfig: NextConfig = { cacheComponents: true, partialPrefetching: true, }; export default nextConfig
In next.config.js: module.exports = { cacheComponents: true, partialPrefetching: true, }
How partialPrefetching works
With partialPrefetching enabled, Next.js prefetches one reusable App Shell per route instead of prefetching per visible link. The App Shell contains rendered output that does not depend on a link's URL. URL-specific content, including content that depends on params or searchParams, resolves after navigation by default. App Shells are cached on the client, so links to the same route reuse one prefetch. This pattern is similar to per-route code splitting in single-page apps, where one artifact per route is shared by every link that points to it.
partialPrefetching config option
partialPrefetching is a configuration option in next.config.ts or next.config.js that enables Partial Prefetching at the app level. The framework prefetches the static parts of each route by default. When set to true, it requires cacheComponents to also be enabled, otherwise next dev and next build throw at config validation. If set to false (the default), there is no change to prefetch behavior.
partialPrefetching requires cacheComponents
The partialPrefetching configuration option requires cacheComponents to be enabled. Without cacheComponents enabled, next dev and next build will throw an error at config validation.
partialPrefetching config flag enables Partial Prefetching
Enable the partialPrefetching flag in next.config.js or set prefetch='partial' on the segment to enable Partial Prefetching for per-link data resolution.
Enable cacheComponents in next.config.ts
To use Cache Components, set cacheComponents to true in next.config.ts. Example: const nextConfig: NextConfig = { cacheComponents: true }