Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: vercel/next.js
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: v14.2.5
Choose a base ref
...
head repository: vercel/next.js
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: v14.2.6
Choose a head ref
  • 5 commits
  • 25 files changed
  • 3 contributors

Commits on Aug 2, 2024

  1. [docs] Backport Multi-Zones docs to 14.x branch (#68460)

    This makes the Multi-Zones docs available in the live nextjs.org site.
    mknichel authored Aug 2, 2024

    Verified

    This commit was created on GitHub.com and signed with GitHub’s verified signature.
    Copy the full SHA
    28110b6 View commit details

Commits on Aug 5, 2024

  1. Fix typo in memory usage docs

    ijjk committed Aug 5, 2024
    Copy the full SHA
    dc40cc9 View commit details
  2. remove invalid line in disabling webpack cache example

    ijjk committed Aug 5, 2024
    Copy the full SHA
    eee87cb View commit details

Commits on Aug 21, 2024

  1. Ensure fetch cache TTL is updated properly (#69164)

    To reduce the number of set requests we were sending upstream we added
    an optimization to skip sending the set request if the cached data
    didn't change after a revalidation. The problem with this optimization
    is the upstream service relies on this set request to know to update the
    cache entries TTL and consider it up to date. This causes unexpected
    revalidations while the cache value hasn't changed and the TTL is kept
    stale.
    
    x-ref: NEXT-3693
    # Conflicts:
    #	packages/next/src/server/lib/incremental-cache/fetch-cache.ts
    #	test/turbopack-build-tests-manifest.json
    ijjk committed Aug 21, 2024
    Copy the full SHA
    d4ca0b9 View commit details
  2. v14.2.6

    vercel-release-bot committed Aug 21, 2024
    Copy the full SHA
    427c01d View commit details
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ Let's explore some strategies and techniques to optimize memory and address comm

Applications with a large amount of dependencies will use more memory.

The [Bundle Analyzer](/docs/app/building-your-application/optimizing/bundle-analyzer) can help you investigate large dependencies in your application that may be able to be removed to improve performance and memory usage.
The [Bundle Analyzer](/docs/app/building-your-application/optimizing/package-bundling#analyzing-javascript-bundles) can help you investigate large dependencies in your application that may be able to be removed to improve performance and memory usage.

## Run `next build` with `--experimental-debug-memory-usage`

@@ -72,11 +72,10 @@ const nextConfig = {
config,
{ buildId, dev, isServer, defaultLoaders, nextRuntime, webpack }
) => {
if (cfg.cache && !dev) {
cfg.cache = Object.freeze({
if (config.cache && !dev) {
config.cache = Object.freeze({
type: 'memory',
})
cfg.cache.maxMemoryGenerations = 0
}
// Important: return the modified config
return config
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
title: Multi-Zones
description: Learn how to build micro-frontends using Next.js Multi-Zones to deploy multiple Next.js apps under a single domain.
---

{/* The content of this doc is shared between the app and pages router. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}

<details open>
<summary>Examples</summary>

- [With Zones](https://github.com/vercel/next.js/tree/canary/examples/with-zones)

</details>

Multi-Zones are an approach to micro-frontends that separate a large application on a domain into smaller Next.js applications that each serve a set of paths. This is useful when there are collections of pages unrelated to the other pages in the application. By moving those pages to a separate zone (i.e., a separate application), you can reduce the size of each application which improves build times and removes code that is only necessary for one of the zones.

For example, let's say you have the following set of pages that you would like to split up:

- `/blog/*` for all blog posts
- `/dashboard/*` for all pages when the user is logged-in to the dashboard
- `/*` for the rest of your website not covered by other zones

With Multi-Zones support, you can create three applications that all are served on the same domain and look the same to the user, but you can develop and deploy each of the applications independently.

<Image
alt="Three zones: A, B, C. Showing a hard navigation between routes from different zones, and soft navigations between routes within the same zone."
srcLight="/docs/light/multi-zones.png"
srcDark="/docs/dark/multi-zones.png"
width="1600"
height="750"
/>

Navigating between pages in the same zone will perform soft navigations, a navigation that does not require reloading the page. For example, in this diagram, navigating from `/` to `/products` will be a soft navigation.

Navigating from a page in one zone to a page in another zone, such as from `/` to `/dashboard`, will perform a hard navigation, unloading the resources of the current page and loading the resources of the new page. Pages that are frequently visited together should live in the same zone to avoid hard navigations.

## How to define a zone

There are no special APIs to define a new zone. A zone is a normal Next.js application where you also configure a [basePath](/docs/app/api-reference/next-config-js/basePath) to avoid conflicts with pages and static files in other zones.

```js filename="next.config.js"
/** @type {import('next').NextConfig} */
const nextConfig = {
basePath: '/blog',
}
```

The default application that will handle all paths not sent to a more specific zone does not need a `basePath`.

Next.js assets, such as JavaScript and CSS, will also be prefixed with `basePath` to make sure that they don't conflict with assets from other zones. These assets will be served under `/basePath/_next/...` for each of the zones.

If the zone serves pages that don't share a common path prefix, such as `/home` and `/blog`, then you can also set [`assetPrefix`](/docs/app/api-reference/next-config-js/assetPrefix) to ensure that all Next.js assets are served under a unique path prefix for the zone without adding a path prefix to the rest of the routes in your application.

## How to route requests to the right zone

With the Multi Zones set-up, you need to route the paths to the correct zone since they are served by different applications. You can use any HTTP proxy to do this, but one of the Next.js applications can also be used to route requests for the entire domain.

To route to the correct zone using a Next.js application, you can use [`rewrites`](/docs/app/api-reference/next-config-js/rewrites). For each path served by a different zone, you would add a rewrite rule to send that path to the domain of the other zone. For example:

```js filename="next.config.js"
async rewrites() {
return [
{
source: '/blog',
destination: `${process.env.BLOG_DOMAIN}/blog`,
},
{
source: '/blog/:path+',
destination: `${process.env.BLOG_DOMAIN}/blog/:path+`,
}
];
}
```

`destination` should be a URL that is served by the zone, including scheme and domain. This should point to the zone's production domain, but it can also be used to route requests to `localhost` in local development.

> **Good to know**: URL paths should be unique to a zone. For example, two zones trying to serve `/blog` would create a routing conflict.
## Linking between zones

Links to paths in a different zone should use an `a` tag instead of the Next.js [`<Link>`](/docs/pages/api-reference/components/link) component. This is because Next.js will try to prefetch and soft navigate to any relative path in `<Link>` component, which will not work across zones.

## Sharing code

The Next.js applications that make up the different zones can live in any repository. However, it is often convenient to put these zones in a [monorepo](https://en.wikipedia.org/wiki/Monorepo) to more easily share code. For zones that live in different repositories, code can also be shared using public or private NPM packages.

Since the pages in different zones may be released at different times, feature flags can be useful for enabling or disabling features in unison across the different zones.

For [Next.js on Vercel](https://vercel.com?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) applications, you can use a [monorepo](https://vercel.com/blog/monorepos-are-changing-how-teams-build-software?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) to deploy all affected zones with a single `git push`.
Original file line number Diff line number Diff line change
@@ -1,33 +1,7 @@
---
title: Multi Zones
description: Learn how to use multi zones to deploy multiple Next.js apps as a single app.
title: Multi-Zones
description: Learn how to build micro-frontends using Next.js Multi-Zones to deploy multiple Next.js apps under a single domain.
source: app/building-your-application/deploying/multi-zones
---

<details open>
<summary>Examples</summary>

- [With Zones](https://github.com/vercel/next.js/tree/canary/examples/with-zones)

</details>

A zone is a single deployment of a Next.js app. You can have multiple zones and merge them as a single app.

For example, let's say you have the following apps:

- An app for serving `/blog/**`
- Another app for serving all other pages

With multi zones support, you can merge both these apps into a single one allowing your customers to browse it using a single URL, but you can develop and deploy both apps independently.

## How to define a zone

There are no zone related APIs. You only need to do the following:

- Make sure to keep only the pages you need in your app, meaning that an app can't have pages from another app, if app `A` has `/blog` then app `B` shouldn't have it too.
- Make sure to configure a [basePath](/docs/app/api-reference/next-config-js/basePath) to avoid conflicts with pages and static files.

## How to merge zones

You can merge zones using [`rewrites`](/docs/pages/api-reference/next-config-js/rewrites) in one of the apps or any HTTP proxy.

For [Next.js on Vercel](https://vercel.com?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) applications, you can use a [monorepo](https://vercel.com/blog/monorepos-are-changing-how-teams-build-software?utm_source=next-site&utm_medium=docs&utm_campaign=next-website) to deploy both apps with a single `git push`.
{/* DO NOT EDIT. The content of this doc is generated from the source above. To edit the content of this page, navigate to the source page in your editor. You can use the `<PagesOnly>Content</PagesOnly>` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */}
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -16,5 +16,5 @@
"registry": "https://registry.npmjs.org/"
}
},
"version": "14.2.5"
"version": "14.2.6"
}
2 changes: 1 addition & 1 deletion packages/create-next-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-next-app",
"version": "14.2.5",
"version": "14.2.6",
"keywords": [
"react",
"next",
4 changes: 2 additions & 2 deletions packages/eslint-config-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "eslint-config-next",
"version": "14.2.5",
"version": "14.2.6",
"description": "ESLint configuration used by Next.js.",
"main": "index.js",
"license": "MIT",
@@ -10,7 +10,7 @@
},
"homepage": "https://nextjs.org/docs/app/building-your-application/configuring/eslint#eslint-config",
"dependencies": {
"@next/eslint-plugin-next": "14.2.5",
"@next/eslint-plugin-next": "14.2.6",
"@rushstack/eslint-patch": "^1.3.3",
"@typescript-eslint/parser": "^5.4.2 || ^6.0.0 || 7.0.0 - 7.2.0",
"eslint-import-resolver-node": "^0.3.6",
2 changes: 1 addition & 1 deletion packages/eslint-plugin-next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/eslint-plugin-next",
"version": "14.2.5",
"version": "14.2.6",
"description": "ESLint plugin for Next.js.",
"main": "dist/index.js",
"license": "MIT",
2 changes: 1 addition & 1 deletion packages/font/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/font",
"version": "14.2.5",
"version": "14.2.6",
"repository": {
"url": "vercel/next.js",
"directory": "packages/font"
2 changes: 1 addition & 1 deletion packages/next-bundle-analyzer/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/bundle-analyzer",
"version": "14.2.5",
"version": "14.2.6",
"main": "index.js",
"types": "index.d.ts",
"license": "MIT",
2 changes: 1 addition & 1 deletion packages/next-codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/codemod",
"version": "14.2.5",
"version": "14.2.6",
"license": "MIT",
"repository": {
"type": "git",
2 changes: 1 addition & 1 deletion packages/next-env/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/env",
"version": "14.2.5",
"version": "14.2.6",
"keywords": [
"react",
"next",
2 changes: 1 addition & 1 deletion packages/next-mdx/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/mdx",
"version": "14.2.5",
"version": "14.2.6",
"main": "index.js",
"license": "MIT",
"repository": {
2 changes: 1 addition & 1 deletion packages/next-plugin-storybook/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/plugin-storybook",
"version": "14.2.5",
"version": "14.2.6",
"repository": {
"url": "vercel/next.js",
"directory": "packages/next-plugin-storybook"
2 changes: 1 addition & 1 deletion packages/next-polyfill-module/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-module",
"version": "14.2.5",
"version": "14.2.6",
"description": "A standard library polyfill for ES Modules supporting browsers (Edge 16+, Firefox 60+, Chrome 61+, Safari 10.1+)",
"main": "dist/polyfill-module.js",
"license": "MIT",
2 changes: 1 addition & 1 deletion packages/next-polyfill-nomodule/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/polyfill-nomodule",
"version": "14.2.5",
"version": "14.2.6",
"description": "A polyfill for non-dead, nomodule browsers.",
"main": "dist/polyfill-nomodule.js",
"license": "MIT",
2 changes: 1 addition & 1 deletion packages/next-swc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/swc",
"version": "14.2.5",
"version": "14.2.6",
"private": true,
"scripts": {
"clean": "node ../../scripts/rm.mjs native",
12 changes: 6 additions & 6 deletions packages/next/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "next",
"version": "14.2.5",
"version": "14.2.6",
"description": "The React Framework",
"main": "./dist/server/next.js",
"license": "MIT",
@@ -92,7 +92,7 @@
]
},
"dependencies": {
"@next/env": "14.2.5",
"@next/env": "14.2.6",
"@swc/helpers": "0.5.5",
"busboy": "1.6.0",
"caniuse-lite": "^1.0.30001579",
@@ -149,10 +149,10 @@
"@jest/types": "29.5.0",
"@mswjs/interceptors": "0.23.0",
"@napi-rs/triples": "1.2.0",
"@next/polyfill-module": "14.2.5",
"@next/polyfill-nomodule": "14.2.5",
"@next/react-refresh-utils": "14.2.5",
"@next/swc": "14.2.5",
"@next/polyfill-module": "14.2.6",
"@next/polyfill-nomodule": "14.2.6",
"@next/react-refresh-utils": "14.2.6",
"@next/swc": "14.2.6",
"@opentelemetry/api": "1.6.0",
"@playwright/test": "1.41.2",
"@taskr/clear": "1.1.0",
24 changes: 2 additions & 22 deletions packages/next/src/server/lib/incremental-cache/fetch-cache.ts
Original file line number Diff line number Diff line change
@@ -103,9 +103,8 @@ export default class FetchCache implements CacheHandler {
process.env.SUSPENSE_CACHE_BASEPATH

if (process.env.SUSPENSE_CACHE_AUTH_TOKEN) {
this.headers[
'Authorization'
] = `Bearer ${process.env.SUSPENSE_CACHE_AUTH_TOKEN}`
this.headers['Authorization'] =
`Bearer ${process.env.SUSPENSE_CACHE_AUTH_TOKEN}`
}

if (scHost) {
@@ -331,25 +330,6 @@ export default class FetchCache implements CacheHandler {
public async set(...args: Parameters<CacheHandler['set']>) {
const [key, data, ctx] = args

const newValue = data?.kind === 'FETCH' ? data.data : undefined
const existingCache = memoryCache?.get(key)
const existingValue = existingCache?.value
if (
existingValue?.kind === 'FETCH' &&
Object.keys(existingValue.data).every(
(field) =>
JSON.stringify(
(existingValue.data as Record<string, string | Object>)[field]
) ===
JSON.stringify((newValue as Record<string, string | Object>)[field])
)
) {
if (DEBUG) {
console.log(`skipping cache set for ${key} as not modified`)
}
return
}

const { fetchCache, fetchIdx, fetchUrl, tags } = ctx
if (!fetchCache) return

2 changes: 1 addition & 1 deletion packages/react-refresh-utils/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/react-refresh-utils",
"version": "14.2.5",
"version": "14.2.6",
"description": "An experimental package providing utilities for React Refresh.",
"repository": {
"url": "vercel/next.js",
4 changes: 2 additions & 2 deletions packages/third-parties/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@next/third-parties",
"version": "14.2.5",
"version": "14.2.6",
"repository": {
"url": "vercel/next.js",
"directory": "packages/third-parties"
@@ -26,7 +26,7 @@
"third-party-capital": "1.0.20"
},
"devDependencies": {
"next": "14.2.5",
"next": "14.2.6",
"outdent": "0.8.0",
"prettier": "2.5.1"
},
Loading