From ce23f318535fa31550a9b91a55c9cf370c3ea934 Mon Sep 17 00:00:00 2001 From: Lee Robinson Date: Wed, 17 Sep 2025 11:25:33 -0500 Subject: [PATCH 01/23] docs: Update command to use `npx` for tracing files (#83903) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This was easier than needing to modify `package.json` or similar. Thank you! _(Hello from the otheeerr siiiiiiiddeeee 🎶)_ --- docs/01-app/02-guides/local-development.mdx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/01-app/02-guides/local-development.mdx b/docs/01-app/02-guides/local-development.mdx index ea92fc32b946b..99acb5d6a312e 100644 --- a/docs/01-app/02-guides/local-development.mdx +++ b/docs/01-app/02-guides/local-development.mdx @@ -181,16 +181,16 @@ It provides detailed information about the time taken for each module to compile 1. Navigate around your application or make edits to files to reproduce the problem. 1. Stop the Next.js development server. 1. A file called `trace-turbopack` will be available in the `.next` folder. -1. You can interpret the file using `next internal trace [path-to-file]`: +1. You can interpret the file using `npx next internal trace [path-to-file]`: ```bash - next internal trace .next/trace-turbopack + npx next internal trace .next/trace-turbopack ``` On versions where `trace` is not available, the command was named `turbo-trace-server`: ```bash - next internal turbo-trace-server .next/trace-turbopack + npx next internal turbo-trace-server .next/trace-turbopack ``` 1. Once the trace server is running you can view the trace at https://trace.nextjs.org/. From 35d8f6034002173a78460055df58c84d7be18947 Mon Sep 17 00:00:00 2001 From: Felix Shih <25448040+fufuShih@users.noreply.github.com> Date: Thu, 18 Sep 2025 16:11:46 +0800 Subject: [PATCH 02/23] fix: add the missing comma in the document example (#83932) ### What? This PR fixes a missing comma in the function parameter in `03-api-reference/03-file-conventions/layout.mdx`. The comma between `children` and `params` parameters was missing in the documentation example, showing incorrect syntax. ### Why? The missing comma in the documentation example shows invalid JavaScript/TypeScript syntax. ### How? - Added missing comma after `children` parameter . **Before:** ```tsx filename="app/dashboard/[team]/layout.tsx" switcher export default async function Layout({ children params, }: { ``` **After:** ```tsx filename="app/dashboard/[team]/layout.tsx" switcher export default async function Layout({ children, params, }: { children: React.ReactNode ``` --- docs/01-app/03-api-reference/03-file-conventions/layout.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/01-app/03-api-reference/03-file-conventions/layout.mdx b/docs/01-app/03-api-reference/03-file-conventions/layout.mdx index 36da2f45c0739..a0d70b3e53edb 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/layout.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/layout.mdx @@ -61,7 +61,7 @@ A promise that resolves to an object containing the [dynamic route parameters](/ ```tsx filename="app/dashboard/[team]/layout.tsx" switcher export default async function Layout({ - children + children, params, }: { children: React.ReactNode From faf0e71253172f98fb5a07ed98545033c6ed3133 Mon Sep 17 00:00:00 2001 From: Joseph Date: Wed, 17 Sep 2025 15:21:18 +0200 Subject: [PATCH 03/23] docs: the as prop is still available in Pages Router (#83864) We accidentally removed the documentation for `as` prop in Pages Router `next/link`. Closes: https://linear.app/vercel/issue/DOC-3140/add-missing-props-as-to-nextlink-reference-page --- docs/01-app/03-api-reference/02-components/link.mdx | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/docs/01-app/03-api-reference/02-components/link.mdx b/docs/01-app/03-api-reference/02-components/link.mdx index db4eb61ff5955..54a16ac543a4a 100644 --- a/docs/01-app/03-api-reference/02-components/link.mdx +++ b/docs/01-app/03-api-reference/02-components/link.mdx @@ -58,6 +58,7 @@ The following props can be passed to the `` component: | Prop | Example | Type | Required | | ----------------------------------- | ------------------------ | ----------------- | -------- | | [`href`](#href-required) | `href="/dashboard"` | String or Object | Yes | +| [`as`](#as) | `as="/post/abc"` | String or Object | - | | [`replace`](#replace) | `replace={false}` | Boolean | - | | [`scroll`](#scroll) | `scroll={false}` | Boolean | - | | [`prefetch`](#prefetch) | `prefetch={false}` | Boolean | - | @@ -452,6 +453,12 @@ export default function Home() { } ``` +### `as` + +Optional decorator for the path that will be shown in the browser URL bar. Before Next.js 9.5.3 this was used for dynamic routes, check our [previous docs](https://github.com/vercel/next.js/blob/v9.5.2/docs/api-reference/next/link.md#dynamic-routes) to see how it worked. + +When this path differs from the one provided in `href` the previous `href`/`as` behavior is used as shown in the [previous docs](https://github.com/vercel/next.js/blob/v9.5.2/docs/api-reference/next/link.md#dynamic-routes). + ### `onNavigate` From 7e1b3230809d2e36244a1914d8782b8818bf047a Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 16 Sep 2025 13:50:47 -0700 Subject: [PATCH 04/23] docs: Fix self-referential link to Middleware in middleware.mdx (#83854) This link was to the current page, which isn't very useful. Link to the getting started page (https://nextjs.org/docs/app/getting-started/route-handlers-and-middleware#middleware) instead --- docs/01-app/03-api-reference/03-file-conventions/middleware.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx index a29cffa570c0b..3d93155119a7e 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx @@ -8,7 +8,7 @@ related: - app/api-reference/functions/next-response --- -The `middleware.js|ts` file is used to write [Middleware](/docs/app/api-reference/file-conventions/middleware) and run code on the server before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly. +The `middleware.js|ts` file is used to write [Middleware](/docs/app/getting-started/route-handlers-and-middleware#middleware) and run code on the server before a request is completed. Then, based on the incoming request, you can modify the response by rewriting, redirecting, modifying the request or response headers, or responding directly. Middleware executes before routes are rendered. It's particularly useful for implementing custom server-side logic like authentication, logging, or handling redirects. From 9edb09e6830b02763ffdf47d75747e939bfed4f3 Mon Sep 17 00:00:00 2001 From: David <75678655+dwrth@users.noreply.github.com> Date: Mon, 15 Sep 2025 13:38:54 +0200 Subject: [PATCH 05/23] docs(metadata): align default function export name with file name (#83796) --- docs/01-app/01-getting-started/14-metadata-and-og-images.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/01-app/01-getting-started/14-metadata-and-og-images.mdx b/docs/01-app/01-getting-started/14-metadata-and-og-images.mdx index 472680b38ddc7..18ea3ec986059 100644 --- a/docs/01-app/01-getting-started/14-metadata-and-og-images.mdx +++ b/docs/01-app/01-getting-started/14-metadata-and-og-images.mdx @@ -51,7 +51,7 @@ export const metadata: Metadata = { description: '...', } -export default function Page() {} +export default function Layout() {} ``` ```jsx filename="app/blog/layout.tsx" switcher @@ -60,7 +60,7 @@ export const metadata = { description: '...', } -export default function Page() {} +export default function Layout() {} ``` You can view a full list of available options, in the [`generateMetadata` documentation](/docs/app/api-reference/functions/generate-metadata#metadata-fields). From 067a5fb82e622d36852add2500229de75f4b3c4d Mon Sep 17 00:00:00 2001 From: Aymeric PINEAU <62554073+aymericzip@users.noreply.github.com> Date: Mon, 15 Sep 2025 08:09:42 -0600 Subject: [PATCH 06/23] Update next-intlayer reference in i18n doc (#83761) [`next-intlayer`](https://intlayer.org/doc/environment/nextjs) is an i18n library that adopts a per-component approach to manage multilingual content in a next.js application. ### Changes - Fix doc related to page-router documentation, - And add App Router realted doc. Co-authored-by: Joseph --- docs/01-app/02-guides/internationalization.mdx | 1 + docs/02-pages/02-guides/internationalization.mdx | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/01-app/02-guides/internationalization.mdx b/docs/01-app/02-guides/internationalization.mdx index 52df7fec50bb6..2096039f4055d 100644 --- a/docs/01-app/02-guides/internationalization.mdx +++ b/docs/01-app/02-guides/internationalization.mdx @@ -215,3 +215,4 @@ export default async function RootLayout({ children, params }) { - [`paraglide-next`](https://inlang.com/m/osslbuzt/paraglide-next-i18n) - [`lingui`](https://lingui.dev) - [`tolgee`](https://tolgee.io/apps-integrations/next) +- [`next-intlayer`](https://intlayer.org/doc/environment/nextjs) diff --git a/docs/02-pages/02-guides/internationalization.mdx b/docs/02-pages/02-guides/internationalization.mdx index 145183f7eba47..8f4a8fd69ab8c 100644 --- a/docs/02-pages/02-guides/internationalization.mdx +++ b/docs/02-pages/02-guides/internationalization.mdx @@ -13,7 +13,7 @@ description: Next.js has built-in support for internationalized routing and lang Next.js has built-in support for internationalized ([i18n](https://en.wikipedia.org/wiki/Internationalization_and_localization#Naming)) routing since `v10.0.0`. You can provide a list of locales, the default locale, and domain-specific locales and Next.js will automatically handle the routing. -The i18n routing support is currently meant to complement existing i18n library solutions like [`react-intl`](https://formatjs.io/docs/getting-started/installation), [`react-i18next`](https://react.i18next.com/), [`lingui`](https://lingui.dev/), [`rosetta`](https://github.com/lukeed/rosetta), [`next-intl`](https://github.com/amannn/next-intl), [`next-translate`](https://github.com/aralroca/next-translate), [`next-multilingual`](https://github.com/Avansai/next-multilingual), [`tolgee`](https://tolgee.io/integrations/next), [`paraglide-next`](https://inlang.com/m/osslbuzt/paraglide-next-i18n), [`next-intlayer`](https://intlayer.org/doc/environment/nextjs) and others by streamlining the routes and locale parsing. +The i18n routing support is currently meant to complement existing i18n library solutions like [`react-intl`](https://formatjs.io/docs/getting-started/installation), [`react-i18next`](https://react.i18next.com/), [`lingui`](https://lingui.dev/), [`rosetta`](https://github.com/lukeed/rosetta), [`next-intl`](https://github.com/amannn/next-intl), [`next-translate`](https://github.com/aralroca/next-translate), [`next-multilingual`](https://github.com/Avansai/next-multilingual), [`tolgee`](https://tolgee.io/integrations/next), [`paraglide-next`](https://inlang.com/m/osslbuzt/paraglide-next-i18n), [`next-intlayer`](https://intlayer.org/doc/environment/nextjs/next-with-page-router) and others by streamlining the routes and locale parsing. ## Getting started From 13df755422132316c0b50116adb29b3c02f15eca Mon Sep 17 00:00:00 2001 From: Luca Krebs <41986129+obendev@users.noreply.github.com> Date: Mon, 15 Sep 2025 15:51:41 +0200 Subject: [PATCH 07/23] docs(data-security): add bun package manager example (#83735) Adds the `bun add server-only` command to the data security guide. This change adds the missing Bun package manager example to the `docs/01-app/02-guides/data-security.mdx` file, ensuring consistency with other documentation sections. Fixes #83734 Co-authored-by: Joseph --- docs/01-app/02-guides/data-security.mdx | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/01-app/02-guides/data-security.mdx b/docs/01-app/02-guides/data-security.mdx index 075d52e701f64..7e336d172c3a3 100644 --- a/docs/01-app/02-guides/data-security.mdx +++ b/docs/01-app/02-guides/data-security.mdx @@ -251,6 +251,10 @@ yarn add server-only pnpm add server-only ``` +```bash package="bun" +bun add server-only +``` + ```ts filename="lib/data.ts" import 'server-only' From 9b552ac3c2fae4c26906612bb4adee5789d599c9 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 16 Sep 2025 14:19:56 +0200 Subject: [PATCH 08/23] docs: Type narrowing using LayoutProps, PageProps (#83692) Make a couple of clarifications: - type resolved by the helpers - ways to narrow down to a narrower union --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> Co-authored-by: Rich Haines --- .../03-file-conventions/dynamic-routes.mdx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/docs/01-app/03-api-reference/03-file-conventions/dynamic-routes.mdx b/docs/01-app/03-api-reference/03-file-conventions/dynamic-routes.mdx index 2c6f9581fc8be..8956ef73866be 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/dynamic-routes.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/dynamic-routes.mdx @@ -113,6 +113,8 @@ The difference between **catch-all** and **optional catch-all** segments is that When using TypeScript, you can add types for `params` depending on your configured route segment — use [`PageProps<'/route'>`](/docs/app/api-reference/file-conventions/page#page-props-helper), [`LayoutProps<'/route'>`](/docs/app/api-reference/file-conventions/layout#layout-props-helper), or [`RouteContext<'/route'>`](/docs/app/api-reference/file-conventions/route#route-context-helper) to type `params` in `page`, `layout`, and `route` respectively. +Route `params` values are typed as `string`, `string[]`, or `undefined` (for optional catch-all segments), because their values aren't known until runtime. Users can enter any URL into the address bar, and these broad types help ensure that your application code handles all these possible cases. + | Route | `params` Type Definition | | ----------------------------------- | ---------------------------------------- | | `app/blog/[slug]/page.js` | `{ slug: string }` | @@ -120,6 +122,24 @@ When using TypeScript, you can add types for `params` depending on your configur | `app/shop/[[...slug]]/page.js` | `{ slug?: string[] }` | | `app/[categoryId]/[itemId]/page.js` | `{ categoryId: string, itemId: string }` | +If you're working on a route where `params` can only have a fixed number of valid values, such as a `[locale]` param with a known set of language codes, you can use runtime validation to handle any invalid params a user may enter, and let the rest of your application work with the narrower type from your known set. + +```tsx filename="/app/[locale]/page.tsx" +import { notFound } from 'next/navigation' +import type { Locale } from '@i18n/types' +import { isValidLocale } from '@i18n/utils' + +function assertValidLocale(value: string): asserts value is Locale { + if (!isValidLocale(value)) notFound() +} + +export default async function Page(props: PageProps<'/[locale]'>) { + const { locale } = await props.params // locale is typed as string + assertValidLocale(locale) + // locale is now typed as Locale +} +``` + ## Behavior - Since the `params` prop is a promise. You must use `async`/`await` or React's use function to access the values. From 8fe38814cbd0a7321ae6549cfc9a6cb17b370a94 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 16 Sep 2025 15:18:32 +0200 Subject: [PATCH 09/23] docs: implications of mutating cookies in server actions (#83691) Ref: https://github.com/vercel/next.js/discussions/83481 Closes: https://linear.app/vercel/issue/DOC-5070/mutating-cookies-invalidates-router-cache Making sure those using cookies in server actions, know that the server tree is re-rendered and merged with the current client tree. --- docs/01-app/01-getting-started/08-updating-data.mdx | 6 +++++- docs/01-app/03-api-reference/04-functions/cookies.mdx | 8 ++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/docs/01-app/01-getting-started/08-updating-data.mdx b/docs/01-app/01-getting-started/08-updating-data.mdx index 693283d8fca8a..ccefe259fdb60 100644 --- a/docs/01-app/01-getting-started/08-updating-data.mdx +++ b/docs/01-app/01-getting-started/08-updating-data.mdx @@ -393,7 +393,11 @@ Calling `redirect` [throws](/docs/app/api-reference/functions/redirect#behavior) ### Cookies -You can `get`, `set`, and `delete` cookies inside a Server Action using the [`cookies`](/docs/app/api-reference/functions/cookies) API: +You can `get`, `set`, and `delete` cookies inside a Server Action using the [`cookies`](/docs/app/api-reference/functions/cookies) API. + +When you [set or delete](/docs/app/api-reference/functions/cookies#understanding-cookie-behavior-in-server-actions) a cookie in a Server Action, Next.js re-renders the current page and its layouts on the server so the **UI reflects the new cookie value**. + +> **Good to know**: The server update applies to the current React tree, re-rendering, mounting, or unmounting components, as needed. Client state is preserved for re-rendered components, and effects re-run if their dependencies changed. ```ts filename="app/actions.ts" switcher 'use server' diff --git a/docs/01-app/03-api-reference/04-functions/cookies.mdx b/docs/01-app/03-api-reference/04-functions/cookies.mdx index 68148521cf9ae..1a36dc874e5dc 100644 --- a/docs/01-app/03-api-reference/04-functions/cookies.mdx +++ b/docs/01-app/03-api-reference/04-functions/cookies.mdx @@ -82,6 +82,14 @@ When working with cookies in Server Components, it's important to understand tha The server can only send instructions (via `Set-Cookie` headers) to tell the browser to store cookies - the actual storage happens on the client side. This is why cookie operations that modify state (`.set`, `.delete`, `.clear`) must be performed in a Route Handler or Server Action where the response headers can be properly set. +## Understanding Cookie Behavior in Server Actions + +After you set or delete a cookie in a Server Action, Next.js re-renders the current page and its layouts on the server so the UI reflects the new cookie value. See the [Caching guide](/docs/app/guides/caching#cookies). + +The UI is not unmounted, but effects that depend on data coming from the server will re-run. + +To refresh cached data too, call [`revalidatePath`](/docs/app/api-reference/functions/revalidatePath) or [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) inside the action. + ## Examples ### Getting a cookie From 873428cbb1c5f052d2eb974e800c9399960ed4ef Mon Sep 17 00:00:00 2001 From: Mohammad Nedaeifard <46691519+OoMNoO@users.noreply.github.com> Date: Thu, 11 Sep 2025 23:07:49 +0200 Subject: [PATCH 10/23] Update content-security-policy.mdx, fix development environment error (#83665) fix _nextjsDevtools csp error which happens in development environment after enabling csp and following the current documents. Full Error: - Refused to apply inline style because it violates the following Content Security Policy directive: "style-src 'self' 'nonce-YmYyMTZmYTQtMzgxNy00ZjYwLWIwMGQtYjBmYjJjNGYzZWQ1' 'unsafe-inline'". Note that 'unsafe-inline' is ignored if either a hash or nonce value is present in the source list. Co-authored-by: Joseph --- docs/01-app/02-guides/content-security-policy.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/01-app/02-guides/content-security-policy.mdx b/docs/01-app/02-guides/content-security-policy.mdx index dcd24b273f6ed..3714ef565645d 100644 --- a/docs/01-app/02-guides/content-security-policy.mdx +++ b/docs/01-app/02-guides/content-security-policy.mdx @@ -548,7 +548,7 @@ export function middleware(request: NextRequest) { const cspHeader = ` default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ''}; - style-src 'self' 'nonce-${nonce}' ${isDev ? "'unsafe-inline'" : ''}; + style-src 'self' ${isDev ? "'unsafe-inline'" : `'nonce-${nonce}'`}; img-src 'self' blob: data:; font-src 'self'; object-src 'none'; @@ -570,7 +570,7 @@ export function middleware(request) { const cspHeader = ` default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic' ${isDev ? "'unsafe-eval'" : ''}; - style-src 'self' 'nonce-${nonce}' ${isDev ? "'unsafe-inline'" : ''}; + style-src 'self' ${isDev ? "'unsafe-inline'" : `'nonce-${nonce}'`}; img-src 'self' blob: data:; font-src 'self'; object-src 'none'; From 71d667253783d210fb045aef8e957bab0ddd8806 Mon Sep 17 00:00:00 2001 From: pontasan <48611107+pontasan@users.noreply.github.com> Date: Mon, 8 Sep 2025 23:47:17 +0900 Subject: [PATCH 11/23] Docs: Add authentication note for external/internal image sources (#83469) **Summary** This PR adds a note to the documentation clarifying the behavior when using external or internal URLs (API Routes) as image sources with Next.js Image Optimization. This change addresses issue #82610. **Details** - Added a note explaining that, for security reasons, request headers are not forwarded to API Routes or external URLs when Image Optimization is used. - Documented that if image data requires authentication, the `unoptimized` property should be considered to disable Image Optimization. **Why** Users may be confused when trying to load images from endpoints that require authentication. This clarification helps developers understand the limitation and how to handle such cases. **References** - [Vercel Changelog: CVE-2025-57752](https://vercel.com/changelog/cve-2025-57752) - [Next.js GitHub Issue #82703](https://github.com/vercel/next.js/issues/82703) --- resolves #82610 --------- Co-authored-by: Joseph Co-authored-by: Steven --- docs/01-app/03-api-reference/02-components/image.mdx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/01-app/03-api-reference/02-components/image.mdx b/docs/01-app/03-api-reference/02-components/image.mdx index d4492dec1d2dc..6b9f8908a298c 100644 --- a/docs/01-app/03-api-reference/02-components/image.mdx +++ b/docs/01-app/03-api-reference/02-components/image.mdx @@ -82,6 +82,9 @@ export default function Page() { } ``` +> **Good to know**: For security reasons, the Image Optimization API using the default [loader](#loader) will _not_ forward headers when fetching the `src` image. +> If the `src` image requires authentication, consider using the [unoptimized](#unoptimized) property to disable Image Optimization. + #### `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. From 1f7d87d3e155befd0b9d9fd9dd8e5f14e5c7c914 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 9 Sep 2025 15:14:57 +0200 Subject: [PATCH 12/23] docs: rewrite+usePathname+prerender hydration error mitigation (#83462) Closes: https://linear.app/vercel/issue/DOC-5040/usepathname-and-rewrites --- .../04-functions/use-pathname.mdx | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/docs/01-app/03-api-reference/04-functions/use-pathname.mdx b/docs/01-app/03-api-reference/04-functions/use-pathname.mdx index a4ae628fc785d..139bcb1ccc2a6 100644 --- a/docs/01-app/03-api-reference/04-functions/use-pathname.mdx +++ b/docs/01-app/03-api-reference/04-functions/use-pathname.mdx @@ -65,6 +65,7 @@ const pathname = usePathname() ```tsx filename="app/example-client-component.tsx" switcher 'use client' +import { useEffect } from 'react' import { usePathname, useSearchParams } from 'next/navigation' function ExampleClientComponent() { @@ -79,6 +80,7 @@ function ExampleClientComponent() { ```jsx filename="app/example-client-component.js" switcher 'use client' +import { useEffect } from 'react' import { usePathname, useSearchParams } from 'next/navigation' function ExampleClientComponent() { @@ -90,6 +92,56 @@ function ExampleClientComponent() { } ``` +### Avoid hydration mismatch with rewrites + +When a page is pre-rendered, the HTML is generated for the source pathname. If the page is then reached through a rewrite using `next.config` or `Middleware`, the browser URL may differ, and `usePathname()` will read the rewritten pathname on the client. + +To avoid hydration mismatches, design the UI so that only a small, isolated part depends on the client pathname. Render a stable fallback on the server and update that part after mount. + +```tsx filename="app/example-client-component.tsx" switcher +'use client' + +import { useEffect, useState } from 'react' +import { usePathname } from 'next/navigation' + +export default function PathnameBadge() { + const pathname = usePathname() + const [clientPathname, setClientPathname] = useState('') + + useEffect(() => { + setClientPathname(pathname) + }, [pathname]) + + return ( +

+ Current pathname: {clientPathname} +

+ ) +} +``` + +```jsx filename="app/example-client-component.js" switcher +'use client' + +import { useEffect, useState } from 'react' +import { usePathname } from 'next/navigation' + +export default function PathnameBadge() { + const pathname = usePathname() + const [clientPathname, setClientPathname] = useState('') + + useEffect(() => { + setClientPathname(pathname) + }, [pathname]) + + return ( +

+ Current pathname: {clientPathname} +

+ ) +} +``` + | Version | Changes | | --------- | ------------------------- | | `v13.0.0` | `usePathname` introduced. | From 529b6edfbcfd8e922d670a218c766e73aa1289dc Mon Sep 17 00:00:00 2001 From: Honda Yuto <132035494+HondaYt@users.noreply.github.com> Date: Fri, 5 Sep 2025 00:18:12 +0900 Subject: [PATCH 13/23] Docs: Fix broken getImageProps sample code (#83436) Co-authored-by: Jiachi Liu --- docs/01-app/03-api-reference/02-components/image.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/01-app/03-api-reference/02-components/image.mdx b/docs/01-app/03-api-reference/02-components/image.mdx index 6b9f8908a298c..f7e6ae96bb23d 100644 --- a/docs/01-app/03-api-reference/02-components/image.mdx +++ b/docs/01-app/03-api-reference/02-components/image.mdx @@ -866,7 +866,7 @@ The `getImageProps` function can be used to get the props that would be passed t ```jsx import { getImageProps } from 'next/image' -const props = getImageProps({ +const { props } = getImageProps({ src: 'https://example.com/image.jpg', alt: 'A scenic mountain view', width: 1200, From 344519ccefdbe3eac093751b31bb21f6a93ceab8 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 26 Aug 2025 12:57:22 +0200 Subject: [PATCH 14/23] Docs/late aug feedback (#82953) - I've seen `NextResponse.next({ headers });` where devs likely meant `NextResponse.next({ request: { headers } });` - for example https://github.com/vercel/next.js/issues/82937 - Explaining further `outputFileTracingIncludes-*` options --------- Co-authored-by: vercel[bot] <35613825+vercel[bot]@users.noreply.github.com> --- .../15-route-handlers-and-middleware.mdx | 4 +- .../01-app/02-guides/backend-for-frontend.mdx | 9 +++ .../03-file-conventions/middleware.mdx | 7 ++ .../04-functions/next-response.mdx | 50 +++++++++++++- .../05-config/01-next-config-js/output.mdx | 65 ++++++++++++++++++- 5 files changed, 129 insertions(+), 6 deletions(-) diff --git a/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx b/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx index aaf276c16774c..25e799c0d4d69 100644 --- a/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx +++ b/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx @@ -109,7 +109,7 @@ export default function Page() { return

Hello, Next.js!

} -// ❌ Conflict +// Conflict // `app/route.ts` export async function POST(request: Request) {} ``` @@ -119,7 +119,7 @@ export default function Page() { return

Hello, Next.js!

} -// ❌ Conflict +// Conflict // `app/route.js` export async function POST(request) {} ``` diff --git a/docs/01-app/02-guides/backend-for-frontend.mdx b/docs/01-app/02-guides/backend-for-frontend.mdx index 19fd62301f558..8757dcf15c9f5 100644 --- a/docs/01-app/02-guides/backend-for-frontend.mdx +++ b/docs/01-app/02-guides/backend-for-frontend.mdx @@ -647,6 +647,15 @@ export function middleware(request) { ## Security +### Working with headers + +Be deliberate about where headers go, and avoid directly passing incoming request headers to the outgoing response. + +- **Upstream request headers**: In Middleware, `NextResponse.next({ request: { headers } })` modifies the headers your server receives and does not expose them to the client. +- **Response headers**: `new Response(..., { headers })`, `NextResponse.json(..., { headers })`, `NextResponse.next({ headers })`, or `response.headers.set(...)` send headers back to the client. If sensitive values were appended to these headers, they will be visible to clients. + +Learn more in [NextResponse headers in Middleware](/docs/app/api-reference/functions/next-response#next). + ### Rate limiting You can implement rate limiting in your Next.js backend. In addition to code-based checks, enable any rate limiting features provided by your host. diff --git a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx index 3d93155119a7e..5290df4bb0472 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx @@ -400,6 +400,13 @@ export function middleware(request) { } ``` +Note that the snippet uses: + +- `NextResponse.next({ request: { headers: requestHeaders } })` to make `requestHeaders` available upstream +- **NOT** `NextResponse.next({ headers: requestHeaders })` which makes `requestHeaders` available to clients + +Learn more in [NextResponse headers in Middleware](/docs/app/api-reference/functions/next-response#next). + > **Good to know**: Avoid setting large headers as it might cause [431 Request Header Fields Too Large](https://developer.mozilla.org/docs/Web/HTTP/Status/431) error depending on your backend web server configuration. ### CORS diff --git a/docs/01-app/03-api-reference/04-functions/next-response.mdx b/docs/01-app/03-api-reference/04-functions/next-response.mdx index 7c61bca8e9f40..c07803a79fd6d 100644 --- a/docs/01-app/03-api-reference/04-functions/next-response.mdx +++ b/docs/01-app/03-api-reference/04-functions/next-response.mdx @@ -127,7 +127,7 @@ import { NextResponse } from 'next/server' return NextResponse.next() ``` -You can also forward `headers` when producing the response: +You can also forward `headers` upstream when producing the response, using `NextResponse.next({ request: { headers } })`: ```ts import { NextResponse } from 'next/server' @@ -136,7 +136,7 @@ import { NextResponse } from 'next/server' const newHeaders = new Headers(request.headers) // Add a new header newHeaders.set('x-version', '123') -// And produce a response with the new headers +// Forward the modified request headers upstream return NextResponse.next({ request: { // New request headers @@ -144,3 +144,49 @@ return NextResponse.next({ }, }) ``` + +This forwards `newHeaders` upstream to the target page, route, or server action, and does not expose them to the client. While this pattern is useful for passing data upstream, it should be used with caution because the headers containing this data may be forwarded to external services. + +In contrast, `NextResponse.next({ headers })` is a shorthand for sending headers from middleware to the client. This is **NOT** good practice and should be avoided. Among other reasons because setting response headers like `Content-Type`, can override framework expectations (for example, the `Content-Type` used by Server Actions), leading to failed submissions or broken streaming responses. + +```ts +import { type NextRequest, NextResponse } from 'next/server' + +async function middleware(request: NextRequest) { + const headers = await injectAuth(request.headers) + // DO NOT forward headers like this + return NextResponse.next({ headers }) +} +``` + +In general, avoid copying all incoming request headers because doing so can leak sensitive data to clients or upstream services. + +Prefer a defensive approach by creating a subset of incoming request headers using an allow-list. For example, you might discard custom `x-*` headers and only forward known-safe headers: + +```ts +import { type NextRequest, NextResponse } from 'next/server' + +function middleware(request: NextRequest) { + const incoming = new Headers(request.headers) + const forwarded = new Headers() + + for (const [name, value] of incoming) { + const headerName = name.toLowerCase() + // Keep only known-safe headers, discard custom x-* and other sensitive ones + if ( + !headerName.startsWith('x-') && + headerName !== 'authorization' && + headerName !== 'cookie' + ) { + // Preserve original header name casing + forwarded.set(name, value) + } + } + + return NextResponse.next({ + request: { + headers: forwarded, + }, + }) +} +``` diff --git a/docs/01-app/03-api-reference/05-config/01-next-config-js/output.mdx b/docs/01-app/03-api-reference/05-config/01-next-config-js/output.mdx index d8ebfb6a12168..4d068fa1bba8d 100644 --- a/docs/01-app/03-api-reference/05-config/01-next-config-js/output.mdx +++ b/docs/01-app/03-api-reference/05-config/01-next-config-js/output.mdx @@ -69,13 +69,15 @@ node .next/standalone/server.js - 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 `outputFileTracingRoot` in your `next.config.js`. ```js filename="packages/web-app/next.config.js" +const path = require('path') + module.exports = { // this includes files from the monorepo base two directories up 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 `outputFileTracingExcludes` and `outputFileTracingIncludes` respectively in `next.config.js`. Each config accepts an object with [minimatch globs](https://www.npmjs.com/package/minimatch) 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. +- 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 `outputFileTracingExcludes` and `outputFileTracingIncludes` respectively in `next.config.js`. Each option accepts an object whose keys are **route globs** (matched with [picomatch](https://www.npmjs.com/package/picomatch#basic-globbing) against the route path, e.g. `/api/hello`) and whose values are **glob patterns resolved from the project root** that specify files to include or exclude in the trace. ```js filename="next.config.js" module.exports = { @@ -91,4 +93,63 @@ module.exports = { } ``` -**Note:** The key of `outputFileTracingIncludes`/`outputFileTracingExcludes` is a [glob](https://www.npmjs.com/package/picomatch#basic-globbing), so special characters need to be escaped. +Using a `src/` directory does not change how you write these options: + +- **Keys** still match the route path (`'/api/hello'`, `'/products/[id]'`, etc.). +- **Values** can reference paths under `src/` since they are resolved relative to the project root. + +```js filename="next.config.js" +module.exports = { + outputFileTracingIncludes: { + '/products/*': ['src/lib/payments/**/*'], + '/*': ['src/config/runtime/**/*.json'], + }, + outputFileTracingExcludes: { + '/api/*': ['src/temp/**/*', 'public/large-logs/**/*'], + }, +} +``` + +You can also target all routes using a global key like `'/*'`: + +```js filename="next.config.js" +module.exports = { + outputFileTracingIncludes: { + '/*': ['src/i18n/locales/**/*.json'], + }, +} +``` + +These options are applied to server traces and do not affect routes that do not produce a server trace file: + +- Edge Runtime routes are not affected. +- Fully static pages are not affected. + +In monorepos or when you need to include files outside the app folder, combine `outputFileTracingRoot` with includes: + +```js filename="next.config.js" +const path = require('path') + +module.exports = { + // Trace from the monorepo root + outputFileTracingRoot: path.join(__dirname, '../../'), + outputFileTracingIncludes: { + '/route1': ['../shared/assets/**/*'], + }, +} +``` + +> **Good to know**: +> +> - Prefer forward slashes (`/`) in patterns for cross-platform compatibility. +> - Keep patterns as narrow as possible to avoid oversized traces (avoid `**/*` at the repo root). + +Common include patterns for native/runtime assets: + +```js filename="next.config.js" +module.exports = { + outputFileTracingIncludes: { + '/*': ['node_modules/sharp/**/*', 'node_modules/aws-crt/dist/bin/**/*'], + }, +} +``` From f00201fb076cbfb14a2002bbb1262db3643538c4 Mon Sep 17 00:00:00 2001 From: ryu <114303361+ryuapp@users.noreply.github.com> Date: Wed, 27 Aug 2025 17:13:06 +0900 Subject: [PATCH 15/23] docs: clarify the location of middleware.ts (#83056) I think the phrase "in the root of your project" is unclear and contradictory if we use `src` directory. https://nextjs.org/docs/app/api-reference/file-conventions/src-folder#:~:text=src/app%20or%20src/pages%20will%20be%20ignored%20if%20app%20or%20pages%20are%20present%20in%20the%20root%20directory. So This PR removes that phrase. --------- Co-authored-by: Joseph Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com> Co-authored-by: Joseph --- .../01-getting-started/15-route-handlers-and-middleware.mdx | 2 +- docs/01-app/03-api-reference/03-file-conventions/middleware.mdx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx b/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx index 25e799c0d4d69..56ef61be32506 100644 --- a/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx +++ b/docs/01-app/01-getting-started/15-route-handlers-and-middleware.mdx @@ -164,7 +164,7 @@ Using fetch with `options.cache`, `options.next.revalidate`, or `options.next.ta ### Convention -Use the file `middleware.ts` (or `.js`) in the root of your project to define Middleware. For example, at the same level as `pages` or `app`, or inside `src` if applicable. +Create a `middleware.ts` (or `.js`) file in the project root, or inside `src` if applicable, so that it is located at the same level as `pages` or `app`. > **Note**: While only one `middleware.ts` file is supported per project, you can still organize your middleware logic into modules. Break out middleware functionalities into separate `.ts` or `.js` files and import them into your main `middleware.ts` file. This allows for cleaner management of route-specific middleware, aggregated in the `middleware.ts` for centralized control. By enforcing a single middleware file, it simplifies configuration, prevents potential conflicts, and optimizes performance by avoiding multiple middleware layers. diff --git a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx index 5290df4bb0472..9a3e0ae85bb12 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx @@ -12,7 +12,7 @@ The `middleware.js|ts` file is used to write [Middleware](/docs/app/getting-star Middleware executes before routes are rendered. It's particularly useful for implementing custom server-side logic like authentication, logging, or handling redirects. -Use the file `middleware.ts` (or .js) in the root of your project to define Middleware. For example, at the same level as `app` or `pages`, or inside `src` if applicable. +Create a `middleware.ts` (or `.js`) file in the project root, or inside `src` if applicable, so that it is located at the same level as `pages` or `app`. ```tsx filename="middleware.ts" switcher import { NextResponse, NextRequest } from 'next/server' From afa0f426bd25b2c74745a175f1db084a333ec118 Mon Sep 17 00:00:00 2001 From: Lorenzo Palmes Date: Thu, 28 Aug 2025 12:52:12 +0100 Subject: [PATCH 16/23] Update middleware node version history with latest stable release (#83166) Updates the middleware version history marking node as stable as [announced in version 15.5](https://nextjs.org/blog/next-15-5#nodejs-middleware-stable) Co-authored-by: Joseph --- docs/01-app/03-api-reference/03-file-conventions/middleware.mdx | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx index 9a3e0ae85bb12..513108ffda78f 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx @@ -680,6 +680,7 @@ Learn how to [configure Middleware](/docs/app/guides/self-hosting#middleware) wh | Version | Changes | | --------- | --------------------------------------------------------------------------------------------- | +| `v15.5.0` | Middleware can now use the Node.js runtime (stable) | | `v15.2.0` | Middleware can now use the Node.js runtime (experimental) | | `v13.1.0` | Advanced Middleware flags added | | `v13.0.0` | Middleware can modify request headers, response headers, and send responses | From 4ecb54c60d5ba3b951221263a50039b8dff93cb1 Mon Sep 17 00:00:00 2001 From: Joseph Date: Thu, 4 Sep 2025 09:04:06 +0200 Subject: [PATCH 17/23] docs: Middleware explicit runtime differences (#83348) In previous docs versions, while not explicitly stated, it was rather clearer that middleware has its own runtime. Also, people who have used bundle-analyzer would for example be familiar with the 3 bundles, or those who have worked with `next.config.js`/instrumentation would understand that there's some different runtimes at play going on there, but those who exclusively work with middleware might still miss on this detail. --------- Co-authored-by: JJ Kasper --- .../03-api-reference/03-file-conventions/middleware.mdx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx index 513108ffda78f..8c0838e3b577a 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/middleware.mdx @@ -12,6 +12,12 @@ The `middleware.js|ts` file is used to write [Middleware](/docs/app/getting-star Middleware executes before routes are rendered. It's particularly useful for implementing custom server-side logic like authentication, logging, or handling redirects. +> **Good to know**: +> +> Middleware is meant to be invoked separately of your render code and in optimized cases deployed to your CDN for fast redirect/rewrite handling, you should not attempt relying on shared modules or globals. +> +> To pass information from Middleware to your application, use [headers](#setting-headers), [cookies](#using-cookies), [rewrites](/docs/app/api-reference/functions/next-response#rewrite), [redirects](/docs/app/api-reference/functions/next-response#redirect), or the URL. + Create a `middleware.ts` (or `.js`) file in the project root, or inside `src` if applicable, so that it is located at the same level as `pages` or `app`. ```tsx filename="middleware.ts" switcher @@ -281,7 +287,7 @@ export function middleware(request) { } ``` -## Using Cookies +### Using Cookies Cookies are regular headers. On a `Request`, they are stored in the `Cookie` header. On a `Response` they are in the `Set-Cookie` header. Next.js provides a convenient way to access and manipulate these cookies through the `cookies` extension on `NextRequest` and `NextResponse`. From 646a64e49c0023ece81af5c49d523f2aeff18d28 Mon Sep 17 00:00:00 2001 From: Benjamin Woodruff Date: Tue, 16 Sep 2025 13:50:47 -0700 Subject: [PATCH 18/23] docs: Fix self-referential link to Middleware in middleware.mdx (#83854) This link was to the current page, which isn't very useful. Link to the getting started page (https://nextjs.org/docs/app/getting-started/route-handlers-and-middleware#middleware) instead From b00b8299c8a83d7bfd341407c63749636becd9a8 Mon Sep 17 00:00:00 2001 From: Joseph Date: Tue, 26 Aug 2025 12:46:27 +0200 Subject: [PATCH 19/23] docs: typed routes manual tsconfig includes (#83031) Docs fix to: https://github.com/vercel/next.js/issues/83010 --- docs/01-app/03-api-reference/05-config/02-typescript.mdx | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/docs/01-app/03-api-reference/05-config/02-typescript.mdx b/docs/01-app/03-api-reference/05-config/02-typescript.mdx index 18d1eeeb10239..1db9969294ebd 100644 --- a/docs/01-app/03-api-reference/05-config/02-typescript.mdx +++ b/docs/01-app/03-api-reference/05-config/02-typescript.mdx @@ -131,6 +131,15 @@ export default nextConfig Next.js will generate a link definition in `.next/types` that contains information about all existing routes in your application, which TypeScript can then use to provide feedback in your editor about invalid links. +> **Good to know**: If you set up your project without `create-next-app`, ensure the generated Next.js types are included by adding `.next/types/**/*.ts` to the `include` array in your `tsconfig.json`: + +```json filename="tsconfig.json" +{ + "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"] +} +``` + Currently, experimental support includes any string literal, including dynamic segments. For non-literal strings, you currently need to manually cast the `href` with `as Route`: ```tsx From d6f714f6ffe6e734a568acacab841866441f08e6 Mon Sep 17 00:00:00 2001 From: Joseph Date: Wed, 27 Aug 2025 22:31:19 +0200 Subject: [PATCH 20/23] docs: Expanded type checks to Pages Router and tsconfigPath (#83096) Closes: https://linear.app/vercel/issue/DOC-5027/tsconfigpath-and-typed-routes-updates Also addresses: https://github.com/vercel/next.js/issues/83109 --- .../05-config/02-typescript.mdx | 78 ++++++++++++++++++- 1 file changed, 74 insertions(+), 4 deletions(-) diff --git a/docs/01-app/03-api-reference/05-config/02-typescript.mdx b/docs/01-app/03-api-reference/05-config/02-typescript.mdx index 1db9969294ebd..f71ba27353566 100644 --- a/docs/01-app/03-api-reference/05-config/02-typescript.mdx +++ b/docs/01-app/03-api-reference/05-config/02-typescript.mdx @@ -111,12 +111,14 @@ const nextConfig = { module.exports = nextConfig ``` - - ### Statically Typed Links Next.js can statically type links to prevent typos and other errors when using `next/link`, improving type safety when navigating between pages. +Works in both the Pages and App Router for the `href` prop in `next/link`. In the App Router, it also types `next/navigation` methods like `push`, `replace`, and `prefetch`. It does not type `next/router` methods in Pages Router. + +Literal `href` strings are validated, while non-literal `href`s may require a cast with `as Route`. + To opt-into this feature, `typedRoutes` need to be enabled and the project needs to be using TypeScript. ```ts filename="next.config.ts" @@ -133,12 +135,20 @@ Next.js will generate a link definition in `.next/types` that contains informati > **Good to know**: If you set up your project without `create-next-app`, ensure the generated Next.js types are included by adding `.next/types/**/*.ts` to the `include` array in your `tsconfig.json`: -```json filename="tsconfig.json" +{/* prettier-ignore-start */} + +```json filename="tsconfig.json" highlight={4} { - "include": ["next-env.d.ts", ".next/types/**/*.ts", "**/*.ts", "**/*.tsx"], + "include": [ + "next-env.d.ts", + ".next/types/**/*.ts", + "**/*.ts", + "**/*.tsx" + ], "exclude": ["node_modules"] } ``` +{/* prettier-ignore-end */} Currently, experimental support includes any string literal, including dynamic segments. For non-literal strings, you currently need to manually cast the `href` with `as Route`: @@ -217,6 +227,8 @@ export default nextConfig > **Good to know**: Types are generated based on the environment variables loaded at development runtime, which excludes variables from `.env.production*` files by default. To include production-specific variables, run `next dev` with `NODE_ENV=production`. + + ### With Async Server Components To use an `async` Server Component with TypeScript, ensure you are using TypeScript `5.1.3` or higher and `@types/react` `18.2.8` or higher. @@ -296,6 +308,64 @@ export default function MyApp({ Component, pageProps }: AppProps) { Since `v10.2.1` Next.js supports [incremental type checking](https://www.typescriptlang.org/tsconfig#incremental) when enabled in your `tsconfig.json`, this can help speed up type checking in larger applications. +### Custom `tsconfig` path + +In some cases, you might want to use a different TypeScript configuration for builds or tooling. To do that, set `typescript.tsconfigPath` in `next.config.ts` to point Next.js to another `tsconfig` file. + +```ts filename="next.config.ts" +import type { NextConfig } from 'next' + +const nextConfig: NextConfig = { + typescript: { + tsconfigPath: 'tsconfig.build.json', + }, +} + +export default nextConfig +``` + +For example, switch to a different config for production builds: + +```ts filename="next.config.ts" +import type { NextConfig } from 'next' + +const isProd = process.env.NODE_ENV === 'production' + +const nextConfig: NextConfig = { + typescript: { + tsconfigPath: isProd ? 'tsconfig.build.json' : 'tsconfig.json', + }, +} + +export default nextConfig +``` + +
+Why you might use a separate `tsconfig` for builds + +You might need to relax checks in scenarios like monorepos, where the build also validates shared dependencies that don't match your project's standards, or when loosening checks in CI to continue delivering while migrating locally to stricter TypeScript settings (and still wanting your IDE to highlight misuse). + +For example, if your project uses `useUnknownInCatchVariables` but some monorepo dependencies still assume `any`: + +```json filename="tsconfig.build.json" +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "useUnknownInCatchVariables": false + } +} +``` + +This keeps your editor strict via `tsconfig.json` while allowing the production build to use relaxed settings. + +
+ +> **Good to know**: +> +> - IDEs typically read `tsconfig.json` for diagnostics and IntelliSense, so you can still see IDE warnings while production builds use the alternate config. Mirror critical options if you want parity in the editor. +> - In development, only `tsconfig.json` is watched for changes. If you edit a different file name via `typescript.tsconfigPath`, restart the dev server to apply changes. +> - The configured file is used in `next dev`, `next build`, `next lint`, and `next typegen`. + ### Disabling TypeScript errors in production Next.js fails your **production build** (`next build`) when TypeScript errors are present in your project. From 2bbad1939afbd09a6762cece4c7235a13092351c Mon Sep 17 00:00:00 2001 From: Joseph Date: Thu, 28 Aug 2025 14:55:15 +0200 Subject: [PATCH 21/23] Docs/typed routes snippets (#83132) A few more improvements to typed routes and friends - showing usage of router methods from `next/navigation` - using Route in other data structures --- .../05-config/02-typescript.mdx | 80 ++++++++++++++++--- 1 file changed, 70 insertions(+), 10 deletions(-) diff --git a/docs/01-app/03-api-reference/05-config/02-typescript.mdx b/docs/01-app/03-api-reference/05-config/02-typescript.mdx index f71ba27353566..136f6a0d0066c 100644 --- a/docs/01-app/03-api-reference/05-config/02-typescript.mdx +++ b/docs/01-app/03-api-reference/05-config/02-typescript.mdx @@ -150,20 +150,44 @@ Next.js will generate a link definition in `.next/types` that contains informati ``` {/* prettier-ignore-end */} -Currently, experimental support includes any string literal, including dynamic segments. For non-literal strings, you currently need to manually cast the `href` with `as Route`: +Currently, support includes any string literal, including dynamic segments. For non-literal strings, you need to manually cast with `as Route`. The example below shows both `next/link` and `next/navigation` usage: -```tsx -import type { Route } from 'next'; +```tsx filename="app/example-client.tsx" +'use client' + +import type { Route } from 'next' import Link from 'next/link' +import { useRouter } from 'next/navigation' -// No TypeScript errors if href is a valid route - - - - +export default function Example() { + const router = useRouter() + const slug = 'nextjs' -// TypeScript errors if href is not a valid route - + return ( + <> + {/* Link: literal and dynamic */} + + + + {/* TypeScript error if href is not a valid route */} + + + {/* Router: literal and dynamic strings are validated */} + + + + + {/* For non-literal strings, cast to Route */} + + + ) +} ``` The same applies for redirecting routes defined by middleware: @@ -203,6 +227,42 @@ function Card({ href }: { href: Route | URL }) { } ``` +You can also type a simple data structure and iterate to render links: + +```ts filename="components/nav-items.ts" +import type { Route } from 'next' + +type NavItem = { + href: T + label: string +} + +export const navItems: NavItem[] = [ + { href: '/', label: 'Home' }, + { href: '/about', label: 'About' }, + { href: '/blog', label: 'Blog' }, +] +``` + +Then, map over the items to render `Link`s: + +```tsx filename="components/nav.tsx" +import Link from 'next/link' +import { navItems } from './nav-items' + +export function Nav() { + return ( + + ) +} +``` + > **How does it work?** > > When running `next dev` or `next build`, Next.js generates a hidden `.d.ts` file inside `.next` that contains information about all existing routes in your application (all valid routes as the `href` type of `Link`). This `.d.ts` file is included in `tsconfig.json` and the TypeScript compiler will check that `.d.ts` and provide feedback in your editor about invalid links. From dd5be98e5e09a8779ba79b17269dc52365f2d6a8 Mon Sep 17 00:00:00 2001 From: Joseph Date: Wed, 3 Sep 2025 13:38:07 +0200 Subject: [PATCH 22/23] docs: relative links that were absolute (#83317) Certain relative links were absolute, which renders them with the -> external arrow - might have been a decision per case, but AFAIK, this is only helpful for those links that are now redirecting to other content --- docs/01-app/02-guides/incremental-static-regeneration.mdx | 4 ++-- docs/01-app/02-guides/package-bundling.mdx | 2 +- docs/01-app/02-guides/videos.mdx | 4 ++-- .../03-file-conventions/01-metadata/manifest.mdx | 2 +- docs/01-app/03-api-reference/03-file-conventions/layout.mdx | 4 ++-- docs/01-app/03-api-reference/04-functions/after.mdx | 2 +- docs/01-app/03-api-reference/04-functions/fetch.mdx | 2 +- docs/01-app/03-api-reference/05-config/02-typescript.mdx | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/01-app/02-guides/incremental-static-regeneration.mdx b/docs/01-app/02-guides/incremental-static-regeneration.mdx index 154bfc1add063..37e533259f730 100644 --- a/docs/01-app/02-guides/incremental-static-regeneration.mdx +++ b/docs/01-app/02-guides/incremental-static-regeneration.mdx @@ -97,7 +97,7 @@ Here's how this example works: 3. After 60 seconds has passed, the next request will still return the cached (now stale) page 4. The cache is invalidated and a new version of the page begins generating in the background 5. Once generated successfully, the next request will return the updated page and cache it for subsequent requests -6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [dynamicParams](https://nextjs.org/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) value. However, if the post does not exist, then 404 is returned. +6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [dynamicParams](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) value. However, if the post does not exist, then 404 is returned.
@@ -196,7 +196,7 @@ Here's how this example works: 3. After 60 seconds has passed, the next request will still return the cached (now stale) page 4. The cache is invalidated and a new version of the page begins generating in the background 5. Once generated successfully, the next request will return the updated page and cache it for subsequent requests -6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [fallback](https://nextjs.org/docs/pages/api-reference/functions/get-static-paths#fallback-false) value. However, if the post does not exist, then 404 is returned. +6. If `/blog/26` is requested, and it exists, the page will be generated on-demand. This behavior can be changed by using a different [fallback](/docs/pages/api-reference/functions/get-static-paths#fallback-false) value. However, if the post does not exist, then 404 is returned. diff --git a/docs/01-app/02-guides/package-bundling.mdx b/docs/01-app/02-guides/package-bundling.mdx index fe93d18b91a10..9967d03435214 100644 --- a/docs/01-app/02-guides/package-bundling.mdx +++ b/docs/01-app/02-guides/package-bundling.mdx @@ -70,7 +70,7 @@ const nextConfig = { module.exports = nextConfig ``` -Next.js also optimizes some libraries automatically, thus they do not need to be included in the optimizePackageImports list. See the [full list](https://nextjs.org/docs/app/api-reference/config/next-config-js/optimizePackageImports). +Next.js also optimizes some libraries automatically, thus they do not need to be included in the optimizePackageImports list. See the [full list](/docs/app/api-reference/config/next-config-js/optimizePackageImports). diff --git a/docs/01-app/02-guides/videos.mdx b/docs/01-app/02-guides/videos.mdx index 048a94446bcec..922c40a055db1 100644 --- a/docs/01-app/02-guides/videos.mdx +++ b/docs/01-app/02-guides/videos.mdx @@ -96,7 +96,7 @@ To embed videos from external platforms, you can use Next.js to fetch the video **1. Create a Server Component for video embedding** -The first step is to create a [Server Component](https://nextjs.org/docs/app/getting-started/server-and-client-components) that generates the appropriate iframe for embedding the video. This component will fetch the source URL for the video and render the iframe. +The first step is to create a [Server Component](/docs/app/getting-started/server-and-client-components) that generates the appropriate iframe for embedding the video. This component will fetch the source URL for the video and render the iframe. ```jsx filename="app/ui/video-component.jsx" export default async function VideoComponent() { @@ -108,7 +108,7 @@ export default async function VideoComponent() { **2. Stream the video component using React Suspense** -After creating the Server Component to embed the video, the next step is to [stream](https://nextjs.org/docs/app/api-reference/file-conventions/loading) the component using [React Suspense](https://react.dev/reference/react/Suspense). +After creating the Server Component to embed the video, the next step is to [stream](/docs/app/api-reference/file-conventions/loading) the component using [React Suspense](https://react.dev/reference/react/Suspense). ```jsx filename="app/page.jsx" import { Suspense } from 'react' diff --git a/docs/01-app/03-api-reference/03-file-conventions/01-metadata/manifest.mdx b/docs/01-app/03-api-reference/03-file-conventions/01-metadata/manifest.mdx index 8772d13e52fbd..ed902ff6840bf 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/01-metadata/manifest.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/01-metadata/manifest.mdx @@ -69,4 +69,4 @@ export default function manifest() { ### Manifest Object -The manifest object contains an extensive list of options that may be updated due to new web standards. For information on all the current options, refer to the `MetadataRoute.Manifest` type in your code editor if using [TypeScript](https://nextjs.org/docs/app/api-reference/config/typescript#ide-plugin) or see the [MDN](https://developer.mozilla.org/docs/Web/Manifest) docs. +The manifest object contains an extensive list of options that may be updated due to new web standards. For information on all the current options, refer to the `MetadataRoute.Manifest` type in your code editor if using [TypeScript](/docs/app/api-reference/config/typescript#ide-plugin) or see the [MDN](https://developer.mozilla.org/docs/Web/Manifest) docs. diff --git a/docs/01-app/03-api-reference/03-file-conventions/layout.mdx b/docs/01-app/03-api-reference/03-file-conventions/layout.mdx index a0d70b3e53edb..de5eb99ff7035 100644 --- a/docs/01-app/03-api-reference/03-file-conventions/layout.mdx +++ b/docs/01-app/03-api-reference/03-file-conventions/layout.mdx @@ -234,7 +234,7 @@ export default function Layout({ children }) { Layouts do not re-render on navigation, so they do not access pathname which would otherwise become stale. -To access the current pathname, you can read it inside a Client Component using the [`usePathname`](https://nextjs.org/docs/app/api-reference/functions/use-pathname) hook. Since Client Components re-render during navigation, they have access to the latest pathname. +To access the current pathname, you can read it inside a Client Component using the [`usePathname`](/docs/app/api-reference/functions/use-pathname) hook. Since Client Components re-render during navigation, they have access to the latest pathname. ```tsx filename="app/ui/breadcrumbs.tsx" switcher 'use client' @@ -312,7 +312,7 @@ export default function Layout({ children }) { Layouts cannot pass data to their `children`. However, you can fetch the same data in a route more than once, and use React [`cache`](https://react.dev/reference/react/cache) to dedupe the requests without affecting performance. -Alternatively, when using [`fetch`](https://nextjs.org/docs/app/api-reference/functions/fetch)in Next.js, requests are automatically deduped. +Alternatively, when using [`fetch`](/docs/app/api-reference/functions/fetch)in Next.js, requests are automatically deduped. ```tsx filename="app/lib/data.ts" switcher export async function getUser(id: string) { diff --git a/docs/01-app/03-api-reference/04-functions/after.mdx b/docs/01-app/03-api-reference/04-functions/after.mdx index a750182ea6314..76c604c3708d1 100644 --- a/docs/01-app/03-api-reference/04-functions/after.mdx +++ b/docs/01-app/03-api-reference/04-functions/after.mdx @@ -5,7 +5,7 @@ description: API Reference for the after function. `after` allows you to schedule work to be executed after a response (or prerender) is finished. This is useful for tasks and other side effects that should not block the response, such as logging and analytics. -It can be used in [Server Components](/docs/app/getting-started/server-and-client-components) (including [`generateMetadata`](https://nextjs.org/docs/app/api-reference/functions/generate-metadata)), [Server Actions](/docs/app/getting-started/updating-data), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Middleware](/docs/app/api-reference/file-conventions/middleware). +It can be used in [Server Components](/docs/app/getting-started/server-and-client-components) (including [`generateMetadata`](/docs/app/api-reference/functions/generate-metadata)), [Server Actions](/docs/app/getting-started/updating-data), [Route Handlers](/docs/app/api-reference/file-conventions/route), and [Middleware](/docs/app/api-reference/file-conventions/middleware). The function accepts a callback that will be executed after the response (or prerender) is finished: diff --git a/docs/01-app/03-api-reference/04-functions/fetch.mdx b/docs/01-app/03-api-reference/04-functions/fetch.mdx index 77d365b3cf5cc..78421658b1d74 100644 --- a/docs/01-app/03-api-reference/04-functions/fetch.mdx +++ b/docs/01-app/03-api-reference/04-functions/fetch.mdx @@ -79,7 +79,7 @@ Set the cache lifetime of a resource (in seconds). [Data Cache](/docs/app/guides fetch(`https://...`, { next: { tags: ['collection'] } }) ``` -Set the cache tags of a resource. Data can then be revalidated on-demand using [`revalidateTag`](https://nextjs.org/docs/app/api-reference/functions/revalidateTag). The max length for a custom tag is 256 characters and the max tag items is 128. +Set the cache tags of a resource. Data can then be revalidated on-demand using [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag). The max length for a custom tag is 256 characters and the max tag items is 128. ## Troubleshooting diff --git a/docs/01-app/03-api-reference/05-config/02-typescript.mdx b/docs/01-app/03-api-reference/05-config/02-typescript.mdx index 136f6a0d0066c..63a67cd56e2a7 100644 --- a/docs/01-app/03-api-reference/05-config/02-typescript.mdx +++ b/docs/01-app/03-api-reference/05-config/02-typescript.mdx @@ -269,7 +269,7 @@ export function Nav() { ### Type IntelliSense for Environment Variables -During development, Next.js generates a `.d.ts` file in `.next/types` that contains information about the loaded environment variables for your editor's IntelliSense. If the same environment variable key is defined in multiple files, it is deduplicated according to the [Environment Variable Load Order](https://nextjs.org/docs/app/building-your-application/configuring/environment-variables#environment-variable-load-order). +During development, Next.js generates a `.d.ts` file in `.next/types` that contains information about the loaded environment variables for your editor's IntelliSense. If the same environment variable key is defined in multiple files, it is deduplicated according to the [Environment Variable Load Order](/docs/app/guides/environment-variables#environment-variable-load-order). To opt-into this feature, `experimental.typedEnv` needs to be enabled and the project needs to be using TypeScript. From 4103f8b4f472bb194d9a4bb1de896b0dd0504448 Mon Sep 17 00:00:00 2001 From: Joseph Date: Fri, 12 Sep 2025 15:12:04 +0200 Subject: [PATCH 23/23] Docs/sep paper cuts (#83689) Addressing `papercuts` found this month - Fixes: #83622 --- docs/01-app/01-getting-started/01-installation.mdx | 6 ++++-- docs/01-app/03-api-reference/02-components/image.mdx | 2 +- .../03-api-reference/04-functions/revalidatePath.mdx | 10 ++++++---- .../03-api-reference/05-config/02-typescript.mdx | 4 ++-- docs/01-app/03-api-reference/06-cli/next.mdx | 5 ++++- docs/01-app/03-api-reference/08-turbopack.mdx | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/docs/01-app/01-getting-started/01-installation.mdx b/docs/01-app/01-getting-started/01-installation.mdx index f4731313715f1..64592fd133a14 100644 --- a/docs/01-app/01-getting-started/01-installation.mdx +++ b/docs/01-app/01-getting-started/01-installation.mdx @@ -63,7 +63,7 @@ Then, add the following scripts to your `package.json` file: ```json filename="package.json" { "scripts": { - "dev": "next dev", + "dev": "next dev --turbopack", "build": "next build", "start": "next start", "lint": "eslint" @@ -73,11 +73,13 @@ Then, add the following scripts to your `package.json` file: These scripts refer to the different stages of developing an application: -- `next dev`: Starts the development server. +- `next dev --turbopack`: Starts the development server using Turbopack. - `next build`: Builds the application for production. - `next start`: Starts the production server. - `eslint`: Runs ESLint. +Turbopack is stable for `dev`. For production builds, Turbopack is in beta. To try it, run `next build --turbopack`. See the [Turbopack docs](/docs/app/api-reference/turbopack) for status and caveats. + ### Create the `app` directory diff --git a/docs/01-app/03-api-reference/02-components/image.mdx b/docs/01-app/03-api-reference/02-components/image.mdx index f7e6ae96bb23d..343f527176842 100644 --- a/docs/01-app/03-api-reference/02-components/image.mdx +++ b/docs/01-app/03-api-reference/02-components/image.mdx @@ -530,7 +530,7 @@ module.exports = { } ``` -If using a version prior to 15.3.0, you can configure `remotePatterns` using the object: +You can also configure `remotePatterns` using the object: ```js filename="next.config.js" module.exports = { diff --git a/docs/01-app/03-api-reference/04-functions/revalidatePath.mdx b/docs/01-app/03-api-reference/04-functions/revalidatePath.mdx index 04c853c60a1f3..eae6b73d8e07a 100644 --- a/docs/01-app/03-api-reference/04-functions/revalidatePath.mdx +++ b/docs/01-app/03-api-reference/04-functions/revalidatePath.mdx @@ -13,7 +13,7 @@ description: API Reference for the revalidatePath function. > **Good to know**: > -> - **Server Functions**: Updates the UI immediately (if viewing the revalidated path). Currently, it also causes all previously visited pages to refresh when navigated to again. This behavior is temporary and will be updated in the future to apply only to the specific path. +> - **Server Functions**: Updates the UI immediately (if viewing the affected path). Currently, it also causes all previously visited pages to refresh when navigated to again. This behavior is temporary and will be updated in the future to apply only to the specific path. > - **Route Handlers**: Marks the path for revalidation. The revalidation is done on the next visit to the specified path. This means calling `revalidatePath` with a dynamic route segment will not immediately trigger many revalidations at once. The invalidation only happens when the path is next visited. ## Parameters @@ -22,8 +22,10 @@ description: API Reference for the revalidatePath function. revalidatePath(path: string, type?: 'page' | 'layout'): void; ``` -- `path`: Either a string representing the filesystem path associated with the data you want to revalidate (for example, `/product/[slug]/page`), or the literal route segment (for example, `/product/123`). Must not exceed 1024 characters. This value is case-sensitive. -- `type`: (optional) `'page'` or `'layout'` string to change the type of path to revalidate. If `path` contains a dynamic segment (for example, `/product/[slug]/page`), this parameter is required. If path refers to the literal route segment, e.g., `/product/1` for a dynamic page (e.g., `/product/[slug]/page`), you should not provide `type`. +- `path`: Either a route pattern corresponding to the data you want to revalidate, for example `/product/[slug]`, or a specific URL, `/product/123`. Do not append `/page` or `/layout`, use the `type` parameter instead. Must not exceed 1024 characters. This value is case-sensitive. +- `type`: (optional) `'page'` or `'layout'` string to change the type of path to revalidate. If `path` contains a dynamic segment, for example `/product/[slug]`, this parameter is required. If `path` is a specific URL, `/product/1`, omit `type`. + +Use a specific URL when you want to refresh a [single page](#revalidating-a-specific-url). Use a route pattern plus `type` to refresh [multiple URLs](#revalidating-a-page-path). ## Returns @@ -34,7 +36,7 @@ revalidatePath(path: string, type?: 'page' | 'layout'): void; The path parameter can point to pages, layouts, or route handlers: - **Pages**: Invalidates the specific page -- **Layouts**: Invalidates the layout and all pages beneath it +- **Layouts**: Invalidates the layout (the `layout.tsx` at that segment), all nested layouts beneath it, and all pages beneath them - **Route Handlers**: Invalidates Data Cache entries accessed within route handlers. For example `revalidatePath("/api/data")` invalidates this GET handler: ```ts filename="app/api/data/route.ts" diff --git a/docs/01-app/03-api-reference/05-config/02-typescript.mdx b/docs/01-app/03-api-reference/05-config/02-typescript.mdx index 63a67cd56e2a7..37cb90fa4249a 100644 --- a/docs/01-app/03-api-reference/05-config/02-typescript.mdx +++ b/docs/01-app/03-api-reference/05-config/02-typescript.mdx @@ -168,7 +168,7 @@ export default function Example() { {/* Link: literal and dynamic */} - + {/* TypeScript error if href is not a valid route */} @@ -182,7 +182,7 @@ export default function Example() { {/* For non-literal strings, cast to Route */} - diff --git a/docs/01-app/03-api-reference/06-cli/next.mdx b/docs/01-app/03-api-reference/06-cli/next.mdx index 9751dd0c877ed..bb69628362d6d 100644 --- a/docs/01-app/03-api-reference/06-cli/next.mdx +++ b/docs/01-app/03-api-reference/06-cli/next.mdx @@ -46,7 +46,7 @@ The following commands are available: | ---------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | `-h, --help` | Show all available options. | | `[directory]` | A directory in which to build the application. If not provided, current directory is used. | -| `--turbopack` | Starts development mode using [Turbopack](/docs/app/api-reference/turbopack). | +| `--turbopack` | Starts development mode using [Turbopack](/docs/app/api-reference/turbopack). Also available as `--turbo`. | | `-p` or `--port ` | Specify a port number on which to start the application. Default: 3000, env: PORT | | `-H`or `--hostname ` | Specify a hostname on which to start the application. Useful for making the application available for other devices on the network. Default: 0.0.0.0 | | `--experimental-https` | Starts the server with HTTPS and generates a self-signed certificate. | @@ -79,6 +79,7 @@ The following options are available for the `next build` command: | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `-h, --help` | Show all available options. | | `[directory]` | A directory on which to build the application. If not provided, the current directory will be used. | +| `--turbopack` | Build using [Turbopack](/docs/app/api-reference/turbopack) (beta). Also available as `--turbo`. | | `-d` or `--debug` | Enables a more verbose build output. With this flag enabled additional build output like rewrites, redirects, and headers will be shown. | | | | `--profile` | Enables production [profiling for React](https://react.dev/reference/react/Profiler). | @@ -214,6 +215,8 @@ next typegen next typegen ./apps/web ``` +> **Good to know**: `next typegen` loads your Next.js config (`next.config.js`, `next.config.mjs`, or `next.config.ts`) using the production build phase. Ensure any required environment variables and dependencies are available so the config can load correctly. + ## Examples ### Debugging prerender errors diff --git a/docs/01-app/03-api-reference/08-turbopack.mdx b/docs/01-app/03-api-reference/08-turbopack.mdx index 2591a3b3f4594..8494c0d14a224 100644 --- a/docs/01-app/03-api-reference/08-turbopack.mdx +++ b/docs/01-app/03-api-reference/08-turbopack.mdx @@ -30,7 +30,7 @@ To enable Turbopack in your Next.js project, add the `--turbopack` flag to the ` } ``` -Currently, Turbopack for `dev` is stable, while `build` is in alpha. We are actively working on production support as Turbopack moves closer to stability. +Currently, Turbopack for `dev` is stable, while `build` is in beta. We are actively working on production support as Turbopack moves closer to stability. ## Supported features