diff --git a/docs/01-getting-started/03-react-essentials.mdx b/docs/01-getting-started/03-react-essentials.mdx index 859f771387f17..b199d7ba1c864 100644 --- a/docs/01-getting-started/03-react-essentials.mdx +++ b/docs/01-getting-started/03-react-essentials.mdx @@ -17,7 +17,7 @@ Server and Client Components allow developers to build applications that span th ### Thinking in Server Components -Similar to how React changed the way we think about building UIs, React Server Components introduce a new mental model for building hybrid applications that leverage the [server and the client](/docs/app/building-your-application/rendering#rendering-environments). +Similar to how React changed the way we think about building UIs, React Server Components introduce a new mental model for building hybrid applications that leverage the server and the client. Instead of React rendering your whole application client-side (such as in the case of Single-Page Applications), React now gives you the flexibility to choose where to render your components based on their purpose. @@ -47,7 +47,7 @@ To make the transition to Server Components easier, all components inside the [A ## Client Components -Client Components enable you to add client-side interactivity to your application. In Next.js, they are [pre-rendered](/docs/app/building-your-application/rendering#component-level-client-and-server-rendering) on the server and [hydrated](/docs/app/building-your-application/rendering#component-level-client-and-server-rendering) on the client. You can think of Client Components as how components in the [Pages Router](/docs/pages) have always worked. +Client Components enable you to add client-side interactivity to your application. In Next.js, they are [pre-rendered](/docs/app/building-your-application/rendering) on the server and hydrated on the client. You can think of Client Components as how components in the [Pages Router](/docs/pages) have always worked. ### The "use client" directive @@ -186,7 +186,7 @@ Behind the scenes, React handles rendering as follows: - On the client, React renders Client Components and _slots in_ the rendered result of Server Components, merging the work done on the server and client. - If any Server Components are nested inside a Client Component, their rendered content will be placed correctly within the Client Component. -> **Good to know**: In Next.js, during the initial page load, both the rendered result of Server Components from the above step and Client Components are [pre-rendered on the server as HTML](/docs/app/building-your-application/rendering#static-and-dynamic-rendering-on-the-server) to produce a faster initial page load. +> **Good to know**: In Next.js, during the initial page load, both the rendered result of Server Components from the above step and Client Components are [pre-rendered on the server as HTML](/docs/app/building-your-application/rendering) to produce a faster initial page load. ### Nesting Server Components inside Client Components @@ -345,7 +345,7 @@ Props passed from the Server to Client Components need to be [serializable](http > **Where is the Network Boundary?** > -> In the App Router, the network boundary is between Server Components and Client Components. This is different from the Pages where the boundary is between `getStaticProps`/`getServerSideProps` and Page Components. Data fetched inside Server Components do not need to be serialized as it doesn't cross the network boundary unless it is passed to a Client Component. Learn more about [data fetching](/docs/app/building-your-application/data-fetching#fetching-data-on-the-server) with Server Components. +> In the App Router, the network boundary is between Server Components and Client Components. This is different from the Pages where the boundary is between `getStaticProps`/`getServerSideProps` and Page Components. Data fetched inside Server Components do not need to be serialized as it doesn't cross the network boundary unless it is passed to a Client Component. Learn more about [data fetching](/docs/app/building-your-application/data-fetching/patterns#fetching-data-on-the-server) with Server Components. ### Keeping Server-Only Code out of Client Components (Poisoning) @@ -860,4 +860,4 @@ In the above example, both the layout and page need to make database queries. Ea When fetching data, you may want to share the result of a `fetch` between a `page` or `layout` and some of its children components. This is an unnecessary coupling between the components and can lead to passing `props` back and forth between components. -Instead, we recommend colocating data fetching alongside the component that consumes the data. [`fetch` requests are automatically deduped](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) in Server Components, so each route segment can request exactly the data it needs without worrying about duplicate requests. Next.js will read the same value from the `fetch` cache. +Instead, we recommend colocating data fetching alongside the component that consumes the data. [`fetch` requests are automatically memoized](/docs/app/building-your-application/caching#request-memoization) in Server Components, so each route segment can request exactly the data it needs without worrying about duplicate requests. Next.js will read the same value from the `fetch` cache. diff --git a/docs/02-app/01-building-your-application/01-routing/02-pages-and-layouts.mdx b/docs/02-app/01-building-your-application/01-routing/02-pages-and-layouts.mdx index 54a6a984b4755..cdd6a122a9e48 100644 --- a/docs/02-app/01-building-your-application/01-routing/02-pages-and-layouts.mdx +++ b/docs/02-app/01-building-your-application/01-routing/02-pages-and-layouts.mdx @@ -111,7 +111,7 @@ export default function DashboardLayout({ > - You can use [Route Groups](/docs/app/building-your-application/routing/route-groups) to opt specific route segments in and out of shared layouts. > - Layouts are [Server Components](/docs/getting-started/react-essentials) by default but can be set to a [Client Component](/docs/getting-started/react-essentials#client-components). > - Layouts can fetch data. View the [Data Fetching](/docs/app/building-your-application/data-fetching) section for more information. -> - Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will [automatically dedupe the requests](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) without affecting performance. +> - Passing data between a parent layout and its children is not possible. However, you can fetch the same data in a route more than once, and React will [automatically dedupe the requests](/docs/app/building-your-application/caching#request-memoization) without affecting performance. > - Layouts do not have access to the current route segment(s). To access route segments, you can use [`useSelectedLayoutSegment`](/docs/app/api-reference/functions/use-selected-layout-segment) or [`useSelectedLayoutSegments`](/docs/app/api-reference/functions/use-selected-layout-segments) in a Client Component. > - `.js`, `.jsx`, or `.tsx` file extensions can be used for Layouts. > - A `layout.js` and `page.js` file can be defined in the same folder. The layout will wrap the page. diff --git a/docs/02-app/01-building-your-application/01-routing/03-linking-and-navigating.mdx b/docs/02-app/01-building-your-application/01-routing/03-linking-and-navigating.mdx index 1c4d5735ac5ce..b35194032532b 100644 --- a/docs/02-app/01-building-your-application/01-routing/03-linking-and-navigating.mdx +++ b/docs/02-app/01-building-your-application/01-routing/03-linking-and-navigating.mdx @@ -2,25 +2,23 @@ title: Linking and Navigating description: Learn how navigation works in Next.js, and how to use the Link Component and `useRouter` hook. related: - description: Learn more about statically typed links with TypeScript. links: + - app/building-your-application/caching - app/building-your-application/configuring/typescript --- -The Next.js router uses [server-centric routing](/docs/app/building-your-application/routing#server-centric-routing-with-client-side-navigation) with [client-side navigation](#how-navigation-works). It supports [instant loading states](/docs/app/building-your-application/routing/loading-ui-and-streaming) and [concurrent rendering](https://react.dev/reference/react/startTransition). This means navigation maintains client-side state, avoids expensive re-renders, is interruptible, and doesn't cause race conditions. +There are two ways to navigate between routes in Next.js: -There are two ways to navigate between routes: - -- [`` Component](#link-component) -- [`useRouter` Hook](#userouter-hook) +- Using the [`` Component](#link-component) +- Using the [`useRouter` Hook](#userouter-hook) This page will go through how to use ``, `useRouter()`, and dive deeper into how navigation works. ## `` Component -`` is a React component that extends the HTML `` element to provide [prefetching](#prefetching) and client-side navigation between routes. It is the primary way to navigate between routes in Next.js. +`` is a built-in component that extends the HTML `` tag to provide [prefetching](#1-prefetching) and client-side navigation between routes. It is the primary way to navigate between routes in Next.js. -To use ``, import it from `next/link`, and pass a `href` prop to the component: +You can use it by importing it from `next/link`, and passing a `href` prop to the component: ```tsx filename="app/page.tsx" switcher import Link from 'next/link' @@ -38,11 +36,11 @@ export default function Page() { } ``` -There are optional props you can pass to ``. See the [API reference](/docs/app/api-reference/components/link) for more information. +There are other optional props you can pass to ``. See the [API reference](/docs/app/api-reference/components/link) for more. -## Examples +### Examples -### Linking to Dynamic Segments +#### Linking to Dynamic Segments When linking to [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes), you can use [template literals and interpolation](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) to generate a list of links. For example, to generate a list of blog posts: @@ -62,7 +60,7 @@ export default function PostList({ posts }) { } ``` -### Checking Active Links +#### Checking Active Links You can use [`usePathname()`](/docs/app/api-reference/functions/use-pathname) to determine if a link is active. For example, to add a class to the active link, you can check if the current `pathname` matches the `href` of the link: @@ -95,15 +93,24 @@ export function Navigation({ navLinks }) { } ``` -### Scrolling to an `id` +#### Scrolling to an `id` + +The default behavior of `` is to scroll to the top of a new route or to maintain the scroll position for backwards and forwards navigation. + +If you'd like to scroll to a specific `id` on navigation, you can append your URL with a `#` hash link or just pass a hash link to the `href` prop. This is possible since `` renders to an `` element. -The default behavior of `` is to [scroll to the top of the route segment that has changed](#focus-and-scroll-management). When there is an `id` defined in `href`, it will scroll to the specific `id`, similarly to a normal `` tag. +```jsx +Settings + +// Output +Settings +``` ## `useRouter()` Hook -The `useRouter` hook allows you to programmatically change routes inside [Client Components](/docs/getting-started/react-essentials). +The `useRouter` hook allows you to programmatically change routes. -To use `useRouter`, import it from `next/navigation`, and call the hook inside your Client Component: +This hook can only be used inside Client Components and is imported from `next/navigation`. ```jsx filename="app/page.js" 'use client' @@ -121,70 +128,64 @@ export default function Page() { } ``` -The `useRouter` provides methods such as `push()`, `refresh()`, and more. See the [API reference](/docs/app/api-reference/functions/use-router) for more information. +For a full list of `useRouter` methods, see the [API reference](/docs/app/api-reference/functions/use-router). > **Recommendation:** Use the `` component to navigate between routes unless you have a specific requirement for using `useRouter`. -## How Navigation Works +## How Routing and Navigation Works -- A route transition is initiated using `` or calling `router.push()`. -- The router updates the URL in the browser's address bar. -- The router avoids unnecessary work by re-using segments that haven't changed (e.g. shared layouts) from the [client-side cache](#client-side-caching-of-rendered-server-components). This is also referred to as [partial rendering](/docs/app/building-your-application/routing#partial-rendering). -- If the [conditions of soft navigation](#conditions-for-soft-navigation) are met, the router fetches the new segment from the cache rather than the server. If not, the router performs a [hard navigation](#hard-navigation) and fetches the Server Component payload from the server. -- If created, [loading UI](/docs/app/building-your-application/routing/loading-ui-and-streaming) is shown from the server while the payload is being fetched. -- The router uses the cached or fresh payload to render the new segments on the client. +The App Router uses a hybrid approach for routing and navigation. On the server, your application code is automatically code-split by route segments. And on the client, Next.js [prefetches](#1-prefetching) and [caches](#2-caching) the route segments. This means, when a user navigates to a new route, the browser doesn't reload the page, and only the route segments that change re-render - improving the navigation experience and performance. -### Client-side Caching of Rendered Server Components +### 1. Prefetching -> **Good to know**: This client-side cache is different from the server-side [Next.js HTTP cache](/docs/app/building-your-application/data-fetching#caching-data). +Prefetching is a way to preload a route in the background before the user visits it. -The new router has an **in-memory client-side cache** that stores the **rendered result** of Server Components (payload). The cache is split by route segments which allows invalidation at any level and ensures consistency across concurrent renders. +There are two ways routes are prefetched in Next.js: -As users navigate around the app, the router will store the payload of previously fetched segments **and** [prefetched](#prefetching) segments in the cache. +- **`` component**: Routes are automatically prefetched as they become visible in the user's viewport. Prefetching happens when the page first loads or when it comes into view through scrolling. +- **`router.prefetch()`**: The `useRouter` hook can be used to prefetch routes programmatically. -This means, for certain cases, the router can re-use the cache instead of making a new request to the server. This improves performance by avoiding re-fetching data and re-rendering components unnecessarily. +The``'s prefetching behavior is different for static and dynamic routes: -### Invalidating the Cache +- [**Static Routes**](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default): `prefetch` defaults to `true`. The entire route is prefetched and cached. +- [**Dynamic Routes**](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering): `prefetch` default to automatic. Only the shared layout down until the first `loading.js` file is prefetched and cached for `30s`. This reduces the cost of fetching an entire dynamic route, and it means you can show an [instant loading state](/docs/app/building-your-application/routing/loading-ui-and-streaming#instant-loading-states) for better visual feedback to users. -[Server Actions](/docs/app/building-your-application/data-fetching/server-actions) can be used to revalidate data on-demand by path ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)). +You can disable prefetching by setting the `prefetch` prop to `false`. -### Prefetching - -Prefetching is a way to preload a route in the background before it's visited. The rendered result of prefetched routes is added to the router's client-side cache. This makes navigating to a prefetched route near-instant. - -By default, routes are prefetched as they become visible in the viewport when using the `` component. This can happen when the page first loads or through scrolling. Routes can also be programmatically prefetched using the `prefetch` method of the [`useRouter()` hook](/docs/app/api-reference/functions/use-router#userouter). - -**Static and Dynamic Routes**: - -- If the route is static, all the Server Component payloads for the route segments will be prefetched. -- If the route is dynamic, the payload from the first shared layout down until the first `loading.js` file is prefetched. This reduces the cost of prefetching the whole route dynamically and allows [instant loading states](/docs/app/building-your-application/routing/loading-ui-and-streaming#instant-loading-states) for dynamic routes. +See the [`` API reference](/docs/app/api-reference/components/link) for more information. > **Good to know**: > -> - Prefetching is only enabled in production. -> - Prefetching can be disabled by passing `prefetch={false}` to ``. +> - Prefetching is not enabled in development, only in production. + +### 2. Caching -### Soft Navigation +Next.js has an **in-memory client-side cache** called the [Router Cache](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data#router-cache). As users navigate around the app, the React Server Component Payload of [prefetched](#1-prefetching) route segments and visited routes are stored in the cache. -On navigation, the cache for changed segments is reused (if it exists), and no new requests are made to the server for data. +This means on navigation, the cache is reused as much as possible, instead of making a new request to the server - improving performance by reducing the number of requests and data transferred. -#### Conditions for Soft Navigation +Learn more about how the [Router Cache](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data) works and how to configure it. -On navigation, Next.js will use soft navigation if the route you are navigating to has been [**prefetched**](#prefetching), and either doesn't include [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes) **or** has the same dynamic parameters as the current route. +#### 3. Partial Rendering -For example, consider the following route that includes a dynamic `[team]` segment: `/dashboard/[team]/*`. The cached segments below `/dashboard/[team]/*` will only be invalidated when the `[team]` parameter changes. +Partial rendering means only the route segments that change on navigation re-render on the client, and any shared segments are preserved. -- Navigating from `/dashboard/team-red/*` to `/dashboard/team-red/*` will be a soft navigation. -- Navigating from `/dashboard/team-red/*` to `/dashboard/team-blue/*` will be a hard navigation. +For example, when navigating between two sibling routes, `/dashboard/settings` and `/dashboard/analytics`, the `settings` and `analytics` pages will be rendered, and the shared `dashboard` layout will be preseved. -### Hard Navigation +How partial rendering works -On navigation, the cache is invalidated and the server refetches data and re-renders the changed segments. +Without partial rendering, each navigation would cause the full page to re-render on the server. Rendering only the segment that changes reduces the amount of data transferred and execution time, leading to improved performance. -### Back/Forward Navigation +#### 4. Soft Navigation -Back and forward navigation ([popstate event](https://developer.mozilla.org/en-US/docs/Web/API/Window/popstate_event)) has a soft navigation behavior. This means, the client-side cache is re-used and navigation is near-instant. +By default, the browser performs a hard navigation between pages. This means the browser reloads the page and resets React state such as `useState` hooks in your app and browser state such as the user's scroll position or focused element. However, in Next.js, the App Router uses soft navigation. This means React only renders the segments that have changed while preserving React and browser state, and there is no full page reload. -### Focus and Scroll Management +#### 5. Back and Forward Navigation -By default, Next.js will set focus and scroll into view the segment that's changed on navigation. +By default, Next.js will maintain the scroll position for backwards and forwards navigation, and re-use route segments in the [Router Cache](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#caching-data). diff --git a/docs/02-app/01-building-your-application/01-routing/05-dynamic-routes.mdx b/docs/02-app/01-building-your-application/01-routing/05-dynamic-routes.mdx index a8216617c1821..edfef950b0d92 100644 --- a/docs/02-app/01-building-your-application/01-routing/05-dynamic-routes.mdx +++ b/docs/02-app/01-building-your-application/01-routing/05-dynamic-routes.mdx @@ -15,7 +15,7 @@ When you don't know the exact segment names ahead of time and want to create rou A Dynamic Segment can be created by wrapping a folder's name in square brackets: `[folderName]`. For example, `[id]` or `[slug]`. -Dynamic Segments are passed as the `params` prop to [`layout`](/docs/app/api-reference/file-conventions/layout), [`page`](/docs/app/api-reference/file-conventions/page), [`route`](/docs/app/building-your-application/routing/router-handlers), and [`generateMetadata`](/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) functions. +Dynamic Segments are passed as the `params` prop to [`layout`](/docs/app/api-reference/file-conventions/layout), [`page`](/docs/app/api-reference/file-conventions/page), [`route`](/docs/app/building-your-application/routing/route-handlers), and [`generateMetadata`](/docs/app/api-reference/functions/generate-metadata#generatemetadata-function) functions. ## Example @@ -45,7 +45,7 @@ See the [generateStaticParams()](#generating-static-params) page to learn how to ## Generating Static Params -The `generateStaticParams` function can be used in combination with [dynamic route segments](/docs/app/building-your-application/routing/dynamic-routes) to [**statically generate**](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default) routes at build time instead of on-demand at request time. +The `generateStaticParams` function can be used in combination with [dynamic route segments](/docs/app/building-your-application/routing/dynamic-routes) to [**statically generate**](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default) routes at build time instead of on-demand at request time. ```tsx filename="app/blog/[slug]/page.tsx" switcher export async function generateStaticParams() { @@ -67,7 +67,7 @@ export async function generateStaticParams() { } ``` -The primary benefit of the `generateStaticParams` function is its smart retrieval of data. If content is fetched within the `generateStaticParams` function using a `fetch` request, the requests are [automatically deduplicated](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping). This means a `fetch` request with the same arguments across multiple `generateStaticParams`, Layouts, and Pages will only be made once, which decreases build times. +The primary benefit of the `generateStaticParams` function is its smart retrieval of data. If content is fetched within the `generateStaticParams` function using a `fetch` request, the requests are [automatically memoized](/docs/app/building-your-application/caching#request-memoization). This means a `fetch` request with the same arguments across multiple `generateStaticParams`, Layouts, and Pages will only be made once, which decreases build times. Use the [migration guide](/docs/app/building-your-application/upgrading/app-router-migration#dynamic-paths-getstaticpaths) if you are migrating from the `pages` directory. diff --git a/docs/02-app/01-building-your-application/01-routing/06-loading-ui-and-streaming.mdx b/docs/02-app/01-building-your-application/01-routing/06-loading-ui-and-streaming.mdx index a70699868d86e..642785ffe7ea3 100644 --- a/docs/02-app/01-building-your-application/01-routing/06-loading-ui-and-streaming.mdx +++ b/docs/02-app/01-building-your-application/01-routing/06-loading-ui-and-streaming.mdx @@ -53,7 +53,7 @@ In the same folder, `loading.js` will be nested inside `layout.js`. It will auto > **Good to know**: > -> - Navigation is immediate, even with [server-centric routing](/docs/app/building-your-application/routing#server-centric-routing-with-client-side-navigation). +> - Navigation is immediate, even with [server-centric routing](/docs/app/building-your-application/routing/linking-and-navigating#how-routing-and-navigation-works). > - Navigation is interruptible, meaning changing routes does not need to wait for the content of the route to fully load before navigating to another route. > - Shared layouts remain interactive while new route segments load. diff --git a/docs/02-app/01-building-your-application/01-routing/08-parallel-routes.mdx b/docs/02-app/01-building-your-application/01-routing/08-parallel-routes.mdx index 158da45f5596a..5a551816c2db1 100644 --- a/docs/02-app/01-building-your-application/01-routing/08-parallel-routes.mdx +++ b/docs/02-app/01-building-your-application/01-routing/08-parallel-routes.mdx @@ -103,20 +103,13 @@ Consider the following folder structure. The `@team` slot has a `settings` direc height="930" /> -If you were to navigate from the root `/` to `/settings`, the content that gets rendered is different based on the type of navigation and the availability of the `default.js` file. +#### Navigation -| | With `@analytics/default.js` | Without `@analytics/default.js` | -| --------------- | ---------------------------------------------------- | ------------------------------------------------- | -| Soft Navigation | `@team/settings/page.js` and `@analytics/page.js` | `@team/settings/page.js` and `@analytics/page.js` | -| Hard Navigation | `@team/settings/page.js` and `@analytics/default.js` | 404 | +On navigation, Next.js will render the slot's previously active state, even if it doesn't match the current URL. -#### Soft Navigation +#### Reload -On a [soft navigation](/docs/app/building-your-application/routing/linking-and-navigating#soft-navigation) - Next.js will render the slot's previously active state, even if it doesn't match the current URL. - -#### Hard Navigation - -On a [hard navigation](/docs/app/building-your-application/routing/linking-and-navigating#hard-navigation) - a navigation that requires a full page reload - Next.js will first try to render the unmatched slot's `default.js` file. If that's not available, a 404 gets rendered. +On reload, Next.js will first try to render the unmatched slot's `default.js` file. If that's not available, a 404 gets rendered. > The 404 for unmatched routes helps ensure that you don't accidentally render a route that shouldn't be parallel rendered. diff --git a/docs/02-app/01-building-your-application/01-routing/09-intercepting-routes.mdx b/docs/02-app/01-building-your-application/01-routing/09-intercepting-routes.mdx index 9ae0950ce4f88..e7594abf6de69 100644 --- a/docs/02-app/01-building-your-application/01-routing/09-intercepting-routes.mdx +++ b/docs/02-app/01-building-your-application/01-routing/09-intercepting-routes.mdx @@ -20,7 +20,7 @@ For example, when clicking on a photo from within a feed, a modal overlaying the height="617" /> -However, when navigating to the photo directly by for example when clicking a shareable URL or by refreshing the page, the entire photo page should render instead of the modal. No route interception should occur. +However, when navigating to the photo by clicking a shareable URL or by refreshing the page, the entire photo page should render instead of the modal. No route interception should occur. Intercepting routes hard navigation **TypeScript Warning:** Although `Response.json()` is valid, native TypeScript types currently shows an error, you can use [`NextResponse.json()`](/docs/app/api-reference/functions/next-response#json) for typed responses instead. -### Dynamic Route Handlers +### Opting out of caching -Route handlers are evaluated dynamically when: +You can opt out of caching by: - Using the `Request` object with the `GET` method. - Using any of the other HTTP methods. @@ -201,9 +201,9 @@ export async function POST(request) {} The following examples show how to combine Route Handlers with other Next.js APIs and features. -### Revalidating Static Data +### Revalidating Cached Data -You can [revalidate static data](/docs/app/building-your-application/data-fetching/revalidating) fetches using the [`next.revalidate`](/docs/app/building-your-application/data-fetching/fetching#revalidating-data) option: +You can [revalidate cached data](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) using the [`next.revalidate`](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) option: ```ts filename="app/items/route.ts" switcher import { NextResponse } from 'next/server' @@ -626,7 +626,7 @@ export async function GET(request) { ### Edge and Node.js Runtimes -Route Handlers have an isomorphic Web API to support both Edge and Node.js runtimes seamlessly, including support for streaming. Since Route Handlers use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) as Pages and Layouts, they support long-awaited features like general-purpose [statically regenerated](/docs/app/building-your-application/data-fetching/revalidating) Route Handlers. +Route Handlers have an isomorphic Web API to support both Edge and Node.js runtimes seamlessly, including support for streaming. Since Route Handlers use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) as Pages and Layouts, they support long-awaited features like general-purpose [statically regenerated](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating#revalidating-data) Route Handlers. You can use the `runtime` segment config option to specify the runtime: diff --git a/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx b/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx index 03e62d8e69157..755e30c56d788 100644 --- a/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx +++ b/docs/02-app/01-building-your-application/01-routing/11-middleware.mdx @@ -127,7 +127,7 @@ The `NextResponse` API allows you to: To produce a response from Middleware, you can: -1. `rewrite` to a route ([Page](/docs/app/building-your-application/routing/pages-and-layouts) or [Route Handler](/docs/app/building-your-application/routing/router-handlers)) that produces a response +1. `rewrite` to a route ([Page](/docs/app/building-your-application/routing/pages-and-layouts) or [Route Handler](/docs/app/building-your-application/routing/route-handlers)) that produces a response 2. return a `NextResponse` directly. See [Producing a Response](#producing-a-response) diff --git a/docs/02-app/01-building-your-application/01-routing/index.mdx b/docs/02-app/01-building-your-application/01-routing/index.mdx index fbab832afa0d9..87b1204b2aa15 100644 --- a/docs/02-app/01-building-your-application/01-routing/index.mdx +++ b/docs/02-app/01-building-your-application/01-routing/index.mdx @@ -95,7 +95,7 @@ Next.js provides a set of special files to create UI with specific behavior in n | [`not-found`](/docs/app/api-reference/file-conventions/not-found) | Not found UI for a segment and its children | | [`error`](/docs/app/building-your-application/routing/error-handling) | Error UI for a segment and its children | | [`global-error`](/docs/app/building-your-application/routing/error-handling) | Global Error UI | -| [`route`](/docs/app/building-your-application/routing/router-handlers) | Server-side API endpoint | +| [`route`](/docs/app/building-your-application/routing/route-handlers) | Server-side API endpoint | | [`template`](/docs/app/building-your-application/routing/pages-and-layouts#templates) | Specialized re-rendered Layout UI | | [`default`](/docs/app/api-reference/file-conventions/default) | Fallback UI for [Parallel Routes](/docs/app/building-your-application/routing/parallel-routes) | @@ -146,30 +146,6 @@ This is because while folders define routes, only the contents returned by `page Learn more about [Project Organization and Colocation](/docs/app/building-your-application/routing/colocation). -## Server-Centric Routing with Client-side Navigation - -Unlike the `pages` directory which uses client-side routing, the App Router uses **server-centric routing** to align with [Server Components](/docs/getting-started/react-essentials#server-components) and [data fetching on the server](/docs/app/building-your-application/data-fetching/fetching). With server-centric routing, the client does not have to download a route map and the same request for Server Components can be used to look up routes. This optimization is useful for all applications, but has a larger impact on applications with many routes. - -Although routing is server-centric, the router uses **client-side navigation** with the [Link Component](/docs/app/building-your-application/routing/linking-and-navigating#link-component) - resembling the behavior of a Single-Page Application. This means when a user navigates to a new route, the browser will not reload the page. Instead, the URL will be updated and Next.js will [only render the segments that change](#partial-rendering). - -Additionally, as users navigate around the app, the router will store the result of the React Server Component payload in an **in-memory client-side cache**. The cache is split by route segments which allows invalidation at any level and ensures consistency across [React's concurrent renders](https://react.dev/blog/2022/03/29/react-v18#what-is-concurrent-react). This means that for certain cases, the cache of a previously fetched segment can be re-used, further improving performance. - -Learn more about [Linking and Navigating](/docs/app/building-your-application/routing/linking-and-navigating). - -## Partial Rendering - -When navigating between sibling routes (e.g. `/dashboard/settings` and `/dashboard/analytics` below), Next.js will only fetch and render the layouts and pages in routes that change. It will **not** re-fetch or re-render anything above the segments in the subtree. This means that in routes that share a layout, the layout will be preserved when a user navigates between sibling pages. - -How partial rendering works - -Without partial rendering, each navigation would cause the full page to re-render on the server. Rendering only the segment that’s updating reduces the amount of data transferred and execution time, leading to improved performance. - ## Advanced Routing Patterns The App Router also provides a set of conventions to help you implement more advanced routing patterns. These include: diff --git a/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx b/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx new file mode 100644 index 0000000000000..3ebf9ecaab742 --- /dev/null +++ b/docs/02-app/01-building-your-application/02-data-fetching/01-fetching-caching-and-revalidating.mdx @@ -0,0 +1,344 @@ +--- +title: Data Fetching, Caching, and Revalidating +nav_title: Fetching, Caching, and Revalidating +description: Learn how to fetch, cache, and revalidate data in your Next.js application. +--- + +Data fetching is a core part of any application. This page goes through how you can fetch, cache, and revalidate data in React and Next.js. + +There are three main ways you can fetch data: + +1. On the server, with the `fetch` API. +2. On the server, with third-party libraries. +3. On the client, with third-party libraries. + +## Fetching Data on the Server with `fetch` + +Next.js extends the native [`fetch` Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to allow you to configure the [caching](#caching-data) and [revalidating](#revalidating-data) behavior for each fetch request on the server. React extends `fetch` to automatically [memoize](/docs/app/building-your-application/data-fetching/patterns#fetching-data-where-its-needed) fetch requests while rendering a React component tree. + +You can use `fetch` with [`async`/`await` in Server Components](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises), in [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and in [Server Actions](/docs/app/building-your-application/data-fetching/server-actions). + +For example: + +```tsx filename="app/page.tsx" switcher +async function getData() { + const res = await fetch('https://api.example.com/...') + // The return value is *not* serialized + // You can return Date, Map, Set, etc. + + if (!res.ok) { + // This will activate the closest `error.js` Error Boundary + throw new Error('Failed to fetch data') + } + + return res.json() +} + +export default async function Page() { + const data = await getData() + + return
+} +``` + +```jsx filename="app/page.js" switcher +async function getData() { + const res = await fetch('https://api.example.com/...') + // The return value is *not* serialized + // You can return Date, Map, Set, etc. + + if (!res.ok) { + // This will activate the closest `error.js` Error Boundary + throw new Error('Failed to fetch data') + } + + return res.json() +} + +export default async function Page() { + const data = await getData() + + return
+} +``` + +> **Good to know**: +> +> Next.js provides helpful functions you may need when fetching data in Server Components such as [`cookies`](/docs/app/api-reference/functions/cookies) and [`headers`](/docs/app/api-reference/functions/headers). These will cause the route to be dynamically rendered as they rely on request time information. +> In Route handlers, `fetch` requests are not memoized as Route Handlers are not part of the React component tree. +> To use `async`/`await` in a Server Component with TypeScript, you'll need to use TypeScript `5.1.3` or higher and `@types/react` `18.2.8` or higher. + +### Caching Data + +Caching stores data so it doesn't need to be re-fetched from your data source on every request. + +By default, Next.js automatically caches the returned values of `fetch` in the [Data Cache](/docs/app/building-your-application/caching#data-cache) on the server. This means that the data can be fetched at build time or request time, cached, and reused on each data request. + +```js +// 'force-cache' is the default, and can be omitted +fetch('https://...', { cache: 'force-cache' }) +``` + +`fetch` requests that use the `POST` method are also automatically cached. Unless it's inside a [Route Handler](/docs/app/building-your-application/routing/route-handlers) that uses the `POST` method, then it will not be cached. + +> **What is the Data Cache?** +> +> The Data Cache is a persistent [HTTP cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching). Depending on your platform, the cache can scale automatically and be [shared across multiple regions](https://vercel.com/docs/infrastructure/data-cache). +> +> > Learn more about the [Data Cache](/docs/app/building-your-application/caching#data-cache). + +### Revalidating Data + +Revalidation is the process of purging the Data Cache and re-fetching the latest data. This is useful when your data changes and you want to ensure you show the latest information. + +Cached data can be revalidated in two ways: + +- **Time-based revalidation**: Automatically revalidate data after a certain amount of time has passed. This is useful for data that changes infrequently and freshness is not as critical. +- **On-demand revalidation**: Manually revalidate data based on an event (e.g. form submission). On-demand revalidation can use a tag-based or path-based approach to revalidate groups of data at once. This is useful when you want to ensure the latest data is shown as soon as possible (e.g. when content from your headless CMS is updated). + +#### Time-based Revalidation + +To revalidate data at a timed interval, you can use the `next.revalidate` option of `fetch` to set the cache lifetime of a resource (in seconds). + +```js +fetch('https://...', { next: { revalidate: 3600 } }) +``` + +Alternatively, to revalidate all `fetch` requests in a route segment, you can use the [Segment Config Options](/docs/app/api-reference/file-conventions/route-segment-config). + +```jsx filename="layout.js / page.js" +export const revalidate = 3600 // revalidate at most every hour +``` + +If you have multiple fetch requests in a statically rendered route, and each has a different revalidation frequency. The lowest time will be used for all requests. For dynamically rendered routes, each `fetch` request will be revalidated independently. + +Learn more about [time-based revalidation](/docs/app/building-your-application/caching#time-based-revalidation). + +#### On-demand Revalidation + +Data can be revalidated on-demand by path ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)) inside a Route Handler or a Server Action. + +Next.js has a cache tagging system for invalidating `fetch` requests across routes. + +1. When using `fetch`, you have the option to tag cache entries with one or more tags. +2. Then, you can call `revalidateTag` to revalidate all entries associated with that tag. + +For example, the following `fetch` request adds the cache tag `collection`: + +```tsx filename="app/page.tsx" switcher +export default async function Page() { + const res = await fetch('https://...', { next: { tags: ['collection'] } }) + const data = await res.json() + // ... +} +``` + +```jsx filename="app/page.js" switcher +export default async function Page() { + const res = await fetch('https://...', { next: { tags: ['collection'] } }) + const data = await res.json() + // ... +} +``` + +If using a Route Handler, you should create a secret token only known by your Next.js app. This secret will be used to prevent unauthorized revalidation attempts. For example, you can access the route (either manually or with a webhook) with the following URL structure: + +``` +https:///api/revalidate?tag=collection&secret= +``` + +```ts filename="app/api/revalidate/route.ts" switcher +import { NextRequest, NextResponse } from 'next/server' +import { revalidateTag } from 'next/cache' + +// e.g a webhook to `your-website.com/api/revalidate?tag=collection&secret=` +export async function GET(request: NextRequest) { + // Check for secret to confirm this is a valid request + if ( + request.nextUrl.searchParams.get('secret') !== process.env.MY_SECRET_TOKEN + ) { + return res.status(401).json({ message: 'Invalid token' }) + } + + const tag = request.nextUrl.searchParams.get('tag') + revalidateTag(tag) + return NextResponse.json({ revalidated: true, now: Date.now() }) +} +``` + +```js filename="app/api/revalidate/route.js" switcher +import { NextResponse } from 'next/server' +import { revalidateTag } from 'next/cache' + +// e.g a webhook to `your-website.com/api/revalidate?tag=collection&secret=` +export async function GET(request) { + // Check for secret to confirm this is a valid request + if ( + request.nextUrl.searchParams.get('secret') !== process.env.MY_SECRET_TOKEN + ) { + return res.status(401).json({ message: 'Invalid token' }) + } + + const tag = request.nextUrl.searchParams.get('tag') + revalidateTag(tag) + return NextResponse.json({ revalidated: true, now: Date.now() }) +} +``` + +Alternatively, you can use [`revalidatePath`](/docs/app/api-reference/functions/revalidatePath) to revalidate all data associated with a path. + +```ts filename="app/api/revalidate/route.ts" switcher +import { NextRequest, NextResponse } from 'next/server' +import { revalidatePath } from 'next/cache' + +export async function GET(request: NextRequest) { + const path = request.nextUrl.searchParams.get('path') + revalidatePath(path) + return NextResponse.json({ revalidated: true, now: Date.now() }) +} +``` + +```js filename="app/api/revalidate/route.js" switcher +import { NextResponse } from 'next/server' +import { revalidatePath } from 'next/cache' + +export async function GET(request) { + const path = request.nextUrl.searchParams.get('path') + revalidatePath(path) + return NextResponse.json({ revalidated: true, now: Date.now() }) +} +``` + +Learn more about [on-demand revalidation](/docs/app/building-your-application/caching#on-demand-revalidation). + +#### Error handling and revalidation + +If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data. + +### Opting out of Data Caching + +`fetch` requests are **not** cached if: + +- The `cache: 'no-store` is added to `fetch` requests. +- The `revalidate: 0` option is added to individual `fetch` requests. +- The `fetch` request is inside a Router Handler that uses the `POST` method. +- The `fetch` request comes after the usage of `headers` or `cookies`. +- The `const dynamic = 'force-dynamic'` route segment option is used. +- The `fetchCache` route segment option is configured to skip cache by default. +- The `fetch` request uses `Authorization` or `Cookie` headers and there's an uncached request above it in the component tree. + +#### Individiual `fetch` Requests + +To opt out of caching for individual `fetch` requests, you can set the `cache` option in `fetch` to `'no-store'`. This will fetch data dynamically, on every request. + +```js +fetch('https://...', { cache: 'no-store' }) +``` + +View all the available `cache` options in the [`fetch` API reference](/docs/app/api-reference/functions/fetch). + +#### Multiple `fetch` Requests + +If you have multiple `fetch` requests in a route segment (e.g. a Layout or Page), you can configure the caching behavior of all data requests in the segment using the [Segment Config Options](/docs/app/api-reference/file-conventions/route-segment-config). + +For example, using `const dynamic = 'force-dynamic` will cause all data to be fetched at request time, and the segment to be rendered dynamically. + +```js filename="layout.js / page.js" +// Add +export const dynamic = 'auto' +``` + +There's an extensive list of Segment Config options, giving you fine-grained control of static and dynamic behavior of a route segment. See the [API reference](/docs/app/api-reference/file-conventions/route-segment-config) for more. + +## Fetching data on the Server with third-party libraries + +In cases where you're using a third-party library that doesn't support or expose `fetch` (for example, a database, CMS, or ORM client), you can configure the caching and revalidating behavior of those requests using the [Route Segment Config Option](/docs/app/api-reference/file-conventions/route-segment-config) and React's `cache` function. + +Whether the data is cached or not will depend on whether the route segment is [statically or dynamically rendered](/docs/app/building-your-application/rendering/static-and-dynamic). If the segment is static (default), the output of the request will be cached and revalidated as part of the route segment. If the segment is dynamic, the output of the request will _not_ be cached and will be re-fetched on every request when the segment is rendered. + +> **Good to know:** +> +> Next.js is working on an API, `unstable_cache`, for configuring the caching and revalidating behavior of individual third-party requests. + +### Example + +In the example below: + +- The `revalidate` option is set to `3600`, meaning the data will be cached and revalidated at most every hour. +- The React `cache` function is used to [memoize](/docs/app/building-your-application/caching#request-memoization) data requests. + +```ts filename="utils/get-item.ts" switcher +import { cache } from 'react' + +export const revalidate = 3600 // revalidate the data at most every hour + +export const getItem = cache(async (id: string) => { + const item = await db.item.findUnique({ id }) + return item +}) +``` + +```js filename="utils/get-item.js" switcher +import { cache } from 'react' + +export const revalidate = 3600 // revalidate the data at most every hour + +export const getItem = cache(async (id) => { + const item = await db.item.findUnique({ id }) + return item +}) +``` + +Although the `getItem` function is called twice, only one query will be made to the database. + +```tsx filename="app/item/layout.tsx" switcher +import { getItem } from '@/utils/get-item' + +export default async function Layout({ + params: { id }, +}: { + params: { id: string } +}) { + const item = await getItem(id) + // ... +} +``` + +```jsx filename="app/item/layout.js" switcher +import { getItem } from '@/utils/get-item' + +export default async function Layout({ params: { id } }) { + const item = await getItem(id) + // ... +} +``` + +```tsx filename="app/item/[id]/page.tsx" switcher +import { getItem } from '@/utils/get-item' + +export default async function Page({ + params: { id }, +}: { + params: { id: string } +}) { + const item = await getItem(id) + // ... +} +``` + +```jsx filename="app/item/[id]/page.js" switcher +import { getItem } from '@/utils/get-item' + +export default async function Page({ params: { id } }) { + const item = await getItem(id) + // ... +} +``` + +## Fetching Data on the Client + +If you need to fetch data on the client, we recommend using a third-party library such as [SWR](https://swr.vercel.app/) or [React Query](https://tanstack.com/query/latest). These libraries provide their own APIs for memoizing requests, caching, revalidating, and mutating data. + +> **Future APIs**: +> +> `use` is a React function that **accepts and handles a promise** returned by a function. Wrapping `fetch` in `use` is currently **not** recommended in Client Components and may trigger multiple re-renders. Learn more about `use` in the [React RFC](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise). diff --git a/docs/02-app/01-building-your-application/02-data-fetching/02-patterns.mdx b/docs/02-app/01-building-your-application/02-data-fetching/02-patterns.mdx new file mode 100644 index 0000000000000..1456d581a8fce --- /dev/null +++ b/docs/02-app/01-building-your-application/02-data-fetching/02-patterns.mdx @@ -0,0 +1,311 @@ +--- +title: Data Fetching Patterns +nav_title: Patterns +description: Learn about common data fetching patterns in React and Next.js. +--- + +There are a few recommended patterns and best practices for fetching data in React and Next.js. This page will go over some of the most common patterns and how to use them. + +### Fetching Data on the Server + +Whenever possible, we recommend fetching data on the server. This allows you to: + +- Have direct access to backend data resources (e.g. databases). +- Keep your application more secure by preventing sensitive information, such as access tokens and API keys, from being exposed to the client. +- Fetch data and render in the same environment. This reduces both the back-and-forth communication between client and server, as well as the [work on the main thread](https://vercel.com/blog/how-react-18-improves-application-performance) on the client. +- Perform multiple data fetches with single round-trip instead of multiple individual requests on the client. +- Reduce client-server [waterfalls](#parallel-and-sequential-data-fetching). +- Depending on your region, data fetching can also happen closer to your data source, reducing latency and improving performance. + +You can fetch data on the server using Server Components, [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/building-your-application/data-fetching/server-actions). + +### Fetching Data Where It's Needed + +If you need to use the same data (e.g. current user) in multiple components in a tree, you do not have to fetch data globally, nor forward props between components. Instead, you can use `fetch` or React `cache` in the component that needs the data without worrying about the performance implications of making multiple requests for the same data. + +This is possible because `fetch` requests are automatically memoized. Learn more about [request memoization](/docs/app/building-your-application/caching#request-memoization) + +> **Good to know**: This also applies to layouts, since it's not possible to pass data between a parent layout and its children. + +### Streaming + +Streaming and [Suspense](https://react.dev/reference/react/Suspense) are React features that allow you to progressively render and incrementally stream rendered units of the UI to the client. + +With Server Components and [nested layouts](/docs/app/building-your-application/routing/pages-and-layouts), you're able to instantly render parts of the page that do not specifically require data, and show a [loading state](/docs/app/building-your-application/routing/loading-ui-and-streaming) for parts of the page that are fetching data. This means the user does not have to wait for the entire page to load before they can start interacting with it. + +Server Rendering with Streaming + +To learn more about Streaming and Suspense, see the [Loading UI](/docs/app/building-your-application/routing/loading-ui-and-streaming) and [Streaming and Suspense](/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) pages. + +### Parallel and Sequential Data Fetching + +When fetching data inside React components, you need to be aware of two data fetching patterns: Parallel and Sequential. + +Sequential and Parallel Data Fetching + +- With **sequential data fetching**, requests in a route are dependent on each other and therefore create waterfalls. There may be cases where you want this pattern because one fetch depends on the result of the other, or you want a condition to be satisfied before the next fetch to save resources. However, this behavior can also be unintentional and lead to longer loading times. +- With **parallel data fetching**, requests in a route are eagerly initiated and will load data at the same time. This reduces client-server waterfalls and the total time it takes to load data. + +#### Sequential Data Fetching + +If you have nested components, and each component fetches its own data, Then, data fetching will happen sequentially if those data requests are different (this doesn't apply to requests for the same data as they are automatically [memoized](/docs/app/building-your-application/caching#request-memoization)). + +For example, the `Playlists` component will only start fetching data once the `Artist` component has finished fetching data because `Playlists` depends on the `artistID` prop: + +```tsx filename="app/artist/page.tsx" switcher +// ... + +async function Playlists({ artistID }: { artistID: string }) { + // Wait for the playlists + const playlists = await getArtistPlaylists(artistID) + + return ( +
    + {playlists.map((playlist) => ( +
  • {playlist.name}
  • + ))} +
+ ) +} + +export default async function Page({ + params: { username }, +}: { + params: { username: string } +}) { + // Wait for the artist + const artist = await getArtist(username) + + return ( + <> +

{artist.name}

+ Loading...}> + + + + ) +} +``` + +```jsx filename="app/artist/page.js" switcher +// ... + +async function Playlists({ artistID }) { + // Wait for the playlists + const playlists = await getArtistPlaylists(artistID) + + return ( +
    + {playlists.map((playlist) => ( +
  • {playlist.name}
  • + ))} +
+ ) +} + +export default async function Page({ params: { username } }) { + // Wait for the artist + const artist = await getArtist(username) + + return ( + <> +

{artist.name}

+ Loading...}> + + + + ) +} +``` + +In cases like this, you can use [`loading.js`](/docs/app/building-your-application/routing/loading-ui-and-streaming) (for route segments) or [React ``](/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) (for nested components) to show an instant loading state while React streams in the result. + +This will prevent the whole route from being blocked by data fetching, and the user will be able to interact with the parts of the page that are not blocked. + +> **Blocking Data Requests:** +> +> An alternative approach to prevent waterfalls is to fetch data globally, at the root of your application, but this will block rendering for all route segments beneath it until the data has finished loading. This can be described as "all or nothing" data fetching. Either you have the entire data for your page or application, or none. +> +> Any fetch requests with `await` will block rendering and data fetching for the entire tree beneath it, unless they are wrapped in a `` boundary or `loading.js` is used. Another alternative is use [parallel data fetching](#parallel-data-fetching) or the [preload pattern](#preloading-data). + +#### Parallel Data Fetching + +To fetch data in parallel, you can eagerly initiate requests by defining them outside the components that use the data, then calling them from inside the component. This saves time by initiating both requests in parallel, however, the user won't see the rendered result until both promises are resolved. + +In the example below, the `getArtist` and `getArtistAlbums` functions are defined outside the `Page` component, then called inside the component, and we wait for both promises to resolve: + +```tsx filename="app/artist/[username]/page.tsx" switcher +import Albums from './albums' + +async function getArtist(username: string) { + const res = await fetch(`https://api.example.com/artist/${username}`) + return res.json() +} + +async function getArtistAlbums(username: string) { + const res = await fetch(`https://api.example.com/artist/${username}/albums`) + return res.json() +} + +export default async function Page({ + params: { username }, +}: { + params: { username: string } +}) { + // Initiate both requests in parallel + const artistData = getArtist(username) + const albumsData = getArtistAlbums(username) + + // Wait for the promises to resolve + const [artist, albums] = await Promise.all([artistData, albumsData]) + + return ( + <> +

{artist.name}

+ + + ) +} +``` + +```jsx filename="app/artist/[username]/page.js" switcher +import Albums from './albums' + +async function getArtist(username) { + const res = await fetch(`https://api.example.com/artist/${username}`) + return res.json() +} + +async function getArtistAlbums(username) { + const res = await fetch(`https://api.example.com/artist/${username}/albums`) + return res.json() +} + +export default async function Page({ params: { username } }) { + // Initiate both requests in parallel + const artistData = getArtist(username) + const albumsData = getArtistAlbums(username) + + // Wait for the promises to resolve + const [artist, albums] = await Promise.all([artistData, albumsData]) + + return ( + <> +

{artist.name}

+ + + ) +} +``` + +To improve the user experience, you can add a [Suspense Boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming) to break up the rendering work and show part of the result as soon as possible. + +### Preloading Data + +Another way to prevent waterfalls is to use the preload pattern. You can optionally create a `preload` function to further optimize parallel data fetching. With this approach, you don't have to pass promises down as props. The `preload` function can also have any name as it's a pattern, not an API. + +```tsx filename="components/Item.tsx" switcher +import { getItem } from '@/utils/get-item' + +export const preload = (id: string) => { + // void evaluates the given expression and returns undefined + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void + void getItem(id) +} +export default async function Item({ id }: { id: string }) { + const result = await getItem(id) + // ... +} +``` + +```jsx filename="components/Item.js" switcher +import { getItem } from '@/utils/get-item' + +export const preload = (id) => { + // void evaluates the given expression and returns undefined + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void + void getItem(id) +} +export default async function Item({ id }) { + const result = await getItem(id) + // ... +} +``` + +```tsx filename="app/item/[id]/page.tsx" switcher +import Item, { preload, checkIsAvailable } from '@/components/Item' + +export default async function Page({ + params: { id }, +}: { + params: { id: string } +}) { + // starting loading item data + preload(id) + // perform another asynchronous task + const isAvailable = await checkIsAvailable() + + return isAvailable ? : null +} +``` + +```jsx filename="app/item/[id]/page.js" switcher +import Item, { preload, checkIsAvailable } from '@/components/Item' + +export default async function Page({ params: { id } }) { + // starting loading item data + preload(id) + // perform another asynchronous task + const isAvailable = await checkIsAvailable() + + return isAvailable ? : null +} +``` + +### Using React `cache`, `server-only`, and the Preload Pattern + +You can combine the `cache` function, the `preload` pattern, and the `server-only` package to create a data fetching utility that can be used throughout your app. + +```ts filename="utils/get-item.ts" switcher +import { cache } from 'react' +import 'server-only' + +export const preload = (id: string) => { + void getItem(id) +} + +export const getItem = cache(async (id: string) => { + // ... +}) +``` + +```js filename="utils/get-item.js" switcher +import { cache } from 'react' +import 'server-only' + +export const preload = (id) => { + void getItem(id) +} + +export const getItem = cache(async (id) => { + // ... +}) +``` + +With this approach, you can eagerly fetch data, cache responses, and guarantee that this data fetching [only happens on the server](/docs/getting-started/react-essentials#keeping-server-only-code-out-of-client-components-poisoning). + +The `utils/get-item` exports can be used by Layouts, Pages, or other components to give them control over when an item's data is fetched. + +> - We recommend using the [`server-only` package](/docs/getting-started/react-essentials#keeping-server-only-code-out-of-client-components-poisoning) to make sure server data fetching functions are never used on the client. diff --git a/docs/02-app/01-building-your-application/03-data-fetching/04-server-actions.mdx b/docs/02-app/01-building-your-application/02-data-fetching/03-server-actions.mdx similarity index 99% rename from docs/02-app/01-building-your-application/03-data-fetching/04-server-actions.mdx rename to docs/02-app/01-building-your-application/02-data-fetching/03-server-actions.mdx index 81e0cd54741aa..05d3afa94291b 100644 --- a/docs/02-app/01-building-your-application/03-data-fetching/04-server-actions.mdx +++ b/docs/02-app/01-building-your-application/02-data-fetching/03-server-actions.mdx @@ -1,7 +1,7 @@ --- title: Server Actions nav_title: Server Actions -description: Use Server Actions to mutate data in your Next.js application. +description: Learn how to mutate data with Server Actions. related: title: Next Steps description: For more information on what to do next, we recommend the following sections diff --git a/docs/02-app/01-building-your-application/02-data-fetching/index.mdx b/docs/02-app/01-building-your-application/02-data-fetching/index.mdx new file mode 100644 index 0000000000000..bc61af8abb696 --- /dev/null +++ b/docs/02-app/01-building-your-application/02-data-fetching/index.mdx @@ -0,0 +1,4 @@ +--- +title: Data Fetching +description: Learn how to fetch, cache, revalidate, and mutate of data React and Next.js. +--- diff --git a/docs/02-app/01-building-your-application/02-rendering/01-static-and-dynamic-rendering.mdx b/docs/02-app/01-building-your-application/02-rendering/01-static-and-dynamic-rendering.mdx deleted file mode 100644 index c585856b73865..0000000000000 --- a/docs/02-app/01-building-your-application/02-rendering/01-static-and-dynamic-rendering.mdx +++ /dev/null @@ -1,56 +0,0 @@ ---- -title: Static and Dynamic Rendering -nav_title: Static and Dynamic -description: Learn about static and dynamic rendering in Next.js. ---- - -In Next.js, a route can be statically or dynamically rendered. - -- In a **static** route, components are rendered on the server at build time. The result of the work is cached and reused on subsequent requests. -- In a **dynamic** route, components are rendered on the server at request time. - -## Static Rendering (Default) - -By default, Next.js statically renders routes to improve performance. This means all the rendering work is done ahead of time and can be served from a Content Delivery Network (CDN) geographically closer to the user. - -## Static Data Fetching (Default) - -By default, Next.js will cache the result of `fetch()` requests that do not specifically opt out of caching behavior. This means that fetch requests that do not set a `cache` option will use the `force-cache` option. - -If any fetch requests in the route use the `revalidate` option, the route will be re-rendered statically during revalidation. - -To learn more about caching data fetching requests, see the [Caching and Revalidating](/docs/app/building-your-application/data-fetching/caching) page. - -## Dynamic Rendering - -During static rendering, if a dynamic function or a dynamic `fetch()` request (no caching) is discovered, Next.js will switch to dynamically rendering the whole route at request time. Any cached data requests can still be re-used during dynamic rendering. - -This table summarizes how [dynamic functions](#dynamic-functions) and [caching](#static-data-fetching-default) affect the rendering behavior of a route: - -| Data Fetching | Dynamic Functions | Rendering | -| --------------- | ----------------- | --------- | -| Static (Cached) | No | Static | -| Static (Cached) | Yes | Dynamic | -| Not Cached | No | Dynamic | -| Not Cached | Yes | Dynamic | - -Note how dynamic functions always opt the route into dynamic rendering, regardless of whether the data fetching is cached or not. In other words, static rendering is dependent not only on the data fetching behavior, but also on the dynamic functions used in the route. - -> **Good to know**: In the future, Next.js will introduce hybrid server-side rendering where layouts and pages in a route can be independently statically or dynamically rendered, instead of the whole route. - -### Dynamic Functions - -Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are: - -- Using [`cookies()`](/docs/app/api-reference/functions/cookies) or [`headers()`](/docs/app/api-reference/functions/headers) in a Server Component will opt the whole route into dynamic rendering at request time. -- Using [`useSearchParams()`](/docs/app/api-reference/functions/use-search-params) in Client Components will skip static rendering and instead render all Client Components up to the nearest parent Suspense boundary on the client. - - We recommend wrapping the Client Component that uses `useSearchParams()` in a `` boundary. This will allow any Client Components above it to be statically rendered. [Example](/docs/app/api-reference/functions/use-search-params#static-rendering). -- Using the [`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional) [Pages](/docs/app/api-reference/file-conventions/page) prop will opt the page into dynamic rendering at request time. - -## Dynamic Data Fetching - -Dynamic data fetches are `fetch()` requests that specifically opt out of caching behavior by setting the `cache` option to `'no-store'` or `revalidate` to `0`. - -The caching options for all `fetch` requests in a layout or page can also be set using the [segment config](/docs/app/api-reference/file-conventions/route-segment-config) object. - -To learn more about Dynamic Data Fetching, see the [Data Fetching](/docs/app/building-your-application/data-fetching/fetching) page. diff --git a/docs/02-app/01-building-your-application/02-rendering/index.mdx b/docs/02-app/01-building-your-application/02-rendering/index.mdx deleted file mode 100644 index 57b6a830413eb..0000000000000 --- a/docs/02-app/01-building-your-application/02-rendering/index.mdx +++ /dev/null @@ -1,73 +0,0 @@ ---- -title: Rendering -description: Learn the differences between Next.js rendering environments, strategies, and runtimes. ---- - -Rendering converts the code you write into user interfaces. - -React 18 and Next.js 13 introduced new ways to render your application. This page will help you understand the differences between rendering environments, strategies, runtimes, and how to opt into them. - -## Rendering Environments - -There are two environments where your application code can be rendered: the client and the server. - -Client and Server Environments - -- The **client** refers to the browser on a user's device that sends a request to a server for your application code. It then turns the response from the server into an interface the user can interact with. -- The **server** refers to the computer in a data center that stores your application code, receives requests from a client, does some computation, and sends back an appropriate response. - -> **Good to know**: Server can refer to computers in regions where your application is deployed to, the [Edge Network](https://vercel.com/docs/concepts/edge-network/overview) where your application code is distributed, or [Content Delivery Networks (CDNs)](https://developer.mozilla.org/en-US/docs/Glossary/CDN) where the result of the rendering work can be cached. - -## Component-level Client and Server Rendering - -Before React 18, the primary way to render your application **using React** was entirely on the client. - -Next.js provided an easier way to break down your application into **pages** and prerender on the server by generating HTML and sending it to the client to be [hydrated](https://react.dev/reference/react-dom/hydrate#hydrating-server-rendered-html) by React. However, this led to additional JavaScript needed on the client to make the initial HTML interactive. - -Now, with [Server and Client Components](/docs/getting-started/react-essentials), React can render on the client **and** the server meaning you can choose the rendering environment at the component level. - -By default, the [`app` router uses **Server Components**](/docs/getting-started/react-essentials#server-components), allowing you to easily render components on the server and reducing the amount of JavaScript sent to the client. - -## Static and Dynamic Rendering on the Server - -In addition to client-side and server-side rendering with React components, Next.js gives you the option to optimize rendering on the server with **Static** and **Dynamic** Rendering. - -### Static Rendering - -With **Static Rendering**, both Server _and_ Client Components can be prerendered on the server at **build time**. The result of the work is [cached](/docs/app/building-your-application/data-fetching/caching) and reused on subsequent requests. The cached result can also be [revalidated](/docs/app/building-your-application/data-fetching#revalidating-data). - -> **Good to know**: This is equivalent to [Static Site Generation (SSG)](/docs/pages/building-your-application/rendering/static-site-generation) and [Incremental Static Regeneration (ISR)](/docs/pages/building-your-application/rendering/incremental-static-regeneration) in the [Pages Router](/docs/pages/building-your-application/rendering). - -Server and Client Components are rendered differently during Static Rendering: - -- Client Components have their HTML and JSON prerendered and cached on the server. The cached result is then sent to the client for hydration. -- Server Components are rendered on the server by React, and their payload is used to generate HTML. The same rendered payload is also used to hydrate the components on the client, resulting in no JavaScript needed on the client. - -### Dynamic Rendering - -With Dynamic Rendering, both Server _and_ Client Components are rendered on the server at **request time**. The result of the work is not cached. - -> **Good to know**: This is equivalent to [Server-Side Rendering (`getServerSideProps()`)](/docs/pages/building-your-application/rendering/server-side-rendering) in the [Pages Router](/docs/pages/building-your-application/rendering). - -To learn more about static and dynamic behavior, see the [Static and Dynamic Rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering) page. To learn more about caching, see the [Caching](/docs/app/building-your-application/data-fetching/caching) sections. - -## Edge and Node.js Runtimes - -On the server, there are two runtimes where your pages can be rendered: - -- The **Node.js Runtime** (default) has access to all Node.js APIs and compatible packages from the ecosystem. -- The **Edge Runtime** is based on [Web APIs](/docs/app/api-reference/edge). - -Both runtimes support [streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) from the server, depending on your deployment infrastructure. - -To learn how to switch between runtimes, see the [Edge and Node.js Runtimes](/docs/app/building-your-application/rendering/edge-and-nodejs-runtimes) page. - -## Next Steps - -Now that you understand the fundamentals of rendering, you can learn more about implementing the different rendering strategies and runtimes: diff --git a/docs/02-app/01-building-your-application/03-data-fetching/01-fetching.mdx b/docs/02-app/01-building-your-application/03-data-fetching/01-fetching.mdx deleted file mode 100644 index aa282804f3e7e..0000000000000 --- a/docs/02-app/01-building-your-application/03-data-fetching/01-fetching.mdx +++ /dev/null @@ -1,401 +0,0 @@ ---- -title: Data Fetching -nav_title: Fetching -description: Learn how to fetch data in your Next.js application. ---- - -The Next.js App Router allows you to fetch data directly in your React components by marking the function as `async` and using `await` for the [Promise](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise). - -Data fetching is built on top of the [`fetch()` Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and React Server Components. When using `fetch()`, requests are [automatically deduped](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) by default. - -Next.js extends the `fetch` options object to allow each request to set its own [caching and revalidating](/docs/app/building-your-application/data-fetching/caching). - -## `async` and `await` in Server Components - -You can use `async` and `await` to fetch data in Server Components. - -```tsx filename="app/page.tsx" switcher -async function getData() { - const res = await fetch('https://api.example.com/...') - // The return value is *not* serialized - // You can return Date, Map, Set, etc. - - // Recommendation: handle errors - if (!res.ok) { - // This will activate the closest `error.js` Error Boundary - throw new Error('Failed to fetch data') - } - - return res.json() -} - -export default async function Page() { - const data = await getData() - - return
-} -``` - -```jsx filename="app/page.js" switcher -async function getData() { - const res = await fetch('https://api.example.com/...') - // The return value is *not* serialized - // You can return Date, Map, Set, etc. - - // Recommendation: handle errors - if (!res.ok) { - // This will activate the closest `error.js` Error Boundary - throw new Error('Failed to fetch data') - } - - return res.json() -} - -export default async function Page() { - const data = await getData() - - return
-} -``` - -> **Good to know**: -> -> 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. - -### Server Component Functions - -Next.js provides helpful server functions you may need when fetching data in Server Components: - -- [`cookies()`](/docs/app/api-reference/functions/cookies) -- [`headers()`](/docs/app/api-reference/functions/headers) - -## `use` in Client Components - -`use` is a new React function that **accepts a promise** conceptually similar to `await`. `use` **handles the promise** returned by a function in a way that is compatible with components, hooks, and Suspense. Learn more about `use` in the [React RFC](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md#usepromise). - -Wrapping `fetch` in `use` is currently **not** recommended in Client Components and may trigger multiple re-renders. For now, if you need to fetch data in a Client Component, we recommend using a third-party library such as [SWR](https://swr.vercel.app/) or [React Query](https://tanstack.com/query/v4). - -> **Good to know**: We'll be adding more examples once `fetch` and `use` work in Client Components. - -## Static Data Fetching - -By default, `fetch` will automatically fetch and [cache data](/docs/app/building-your-application/data-fetching/caching) indefinitely. - -```ts -fetch('https://...') // cache: 'force-cache' is the default -``` - -### Revalidating Data - -To revalidate [cached data](/docs/app/building-your-application/data-fetching/caching) at a timed interval, you can use the `next.revalidate` option in `fetch()` to set the `cache` lifetime of a resource (in seconds). - -```ts -fetch('https://...', { next: { revalidate: 10 } }) -``` - -See [Revalidating Data](/docs/app/building-your-application/data-fetching/revalidating) for more information. - -> **Good to know**: -> -> Caching at the fetch level with `revalidate` or `cache: 'force-cache'` stores the data across requests in a shared cache. You should avoid using it for user-specific data (i.e. requests that derive data from `cookies()` or `headers()`) - -## Dynamic Data Fetching - -To fetch fresh data on every `fetch` request, use the `cache: 'no-store'` option. - -```ts -fetch('https://...', { cache: 'no-store' }) -``` - -## Data Fetching Patterns - -### Parallel Data Fetching - -To minimize client-server waterfalls, we recommend this pattern to fetch data in parallel: - -```tsx filename="app/artist/[username]/page.tsx" switcher -import Albums from './albums' - -async function getArtist(username: string) { - const res = await fetch(`https://api.example.com/artist/${username}`) - return res.json() -} - -async function getArtistAlbums(username: string) { - const res = await fetch(`https://api.example.com/artist/${username}/albums`) - return res.json() -} - -export default async function Page({ - params: { username }, -}: { - params: { username: string } -}) { - // Initiate both requests in parallel - const artistData = getArtist(username) - const albumsData = getArtistAlbums(username) - - // Wait for the promises to resolve - const [artist, albums] = await Promise.all([artistData, albumsData]) - - return ( - <> -

{artist.name}

- - - ) -} -``` - -```jsx filename="app/artist/[username]/page.js" switcher -import Albums from './albums' - -async function getArtist(username) { - const res = await fetch(`https://api.example.com/artist/${username}`) - return res.json() -} - -async function getArtistAlbums(username) { - const res = await fetch(`https://api.example.com/artist/${username}/albums`) - return res.json() -} - -export default async function Page({ params: { username } }) { - // Initiate both requests in parallel - const artistData = getArtist(username) - const albumsData = getArtistAlbums(username) - - // Wait for the promises to resolve - const [artist, albums] = await Promise.all([artistData, albumsData]) - - return ( - <> -

{artist.name}

- - - ) -} -``` - -By starting the fetch prior to calling `await` in the Server Component, each request can eagerly start to fetch requests at the same time. This sets the components up so you can avoid waterfalls. - -We can save time by initiating both requests in parallel, however, the user won't see the rendered result until both promises are resolved. - -To improve the user experience, you can add a [suspense boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming) to break up the rendering work and show part of the result as soon as possible: - -```tsx filename="artist/[username]/page.tsx" switcher -import { getArtist, getArtistAlbums, type Album } from './api' - -export default async function Page({ - params: { username }, -}: { - params: { username: string } -}) { - // Initiate both requests in parallel - const artistData = getArtist(username) - const albumData = getArtistAlbums(username) - - // Wait for the artist's promise to resolve first - const artist = await artistData - - return ( - <> -

{artist.name}

- {/* Send the artist information first, - and wrap albums in a suspense boundary */} - Loading...}> - - - - ) -} - -// Albums Component -async function Albums({ promise }: { promise: Promise }) { - // Wait for the albums promise to resolve - const albums = await promise - - return ( -
    - {albums.map((album) => ( -
  • {album.name}
  • - ))} -
- ) -} -``` - -```jsx filename="artist/[username]/page.js" switcher -import { getArtist, getArtistAlbums } from './api' - -export default async function Page({ params: { username } }) { - // Initiate both requests in parallel - const artistData = getArtist(username) - const albumData = getArtistAlbums(username) - - // Wait for the artist's promise to resolve first - const artist = await artistData - - return ( - <> -

{artist.name}

- {/* Send the artist information first, - and wrap albums in a suspense boundary */} - Loading...}> - - - - ) -} - -// Albums Component -async function Albums({ promise }) { - // Wait for the albums promise to resolve - const albums = await promise - - return ( -
    - {albums.map((album) => ( -
  • {album.name}
  • - ))} -
- ) -} -``` - -Take a look at the [preloading pattern](/docs/app/building-your-application/data-fetching/caching#preload-pattern-with-cache) for more information on improving components structure. - -### Sequential Data Fetching - -To fetch data sequentially, you can `fetch` directly inside the component that needs it, or you can `await` the result of `fetch` inside the component that needs it: - -```tsx filename="app/artist/page.tsx" switcher -// ... - -async function Playlists({ artistID }: { artistID: string }) { - // Wait for the playlists - const playlists = await getArtistPlaylists(artistID) - - return ( -
    - {playlists.map((playlist) => ( -
  • {playlist.name}
  • - ))} -
- ) -} - -export default async function Page({ - params: { username }, -}: { - params: { username: string } -}) { - // Wait for the artist - const artist = await getArtist(username) - - return ( - <> -

{artist.name}

- Loading...}> - - - - ) -} -``` - -```jsx filename="app/artist/page.js" switcher -// ... - -async function Playlists({ artistID }) { - // Wait for the playlists - const playlists = await getArtistPlaylists(artistID) - - return ( -
    - {playlists.map((playlist) => ( -
  • {playlist.name}
  • - ))} -
- ) -} - -export default async function Page({ params: { username } }) { - // Wait for the artist - const artist = await getArtist(username) - - return ( - <> -

{artist.name}

- Loading...}> - - - - ) -} -``` - -By fetching data inside the component, each fetch request and nested segment in the route cannot start fetching data and rendering until the previous request or segment has completed. - -### Blocking Rendering in a Route - -By fetching data in a [layout](/docs/app/building-your-application/routing/pages-and-layouts), rendering for all route segments beneath it can only start once the data has finished loading. - -In the `pages` directory, pages using server-rendering would show the browser loading spinner until `getServerSideProps` had finished, then render the React component for that page. This can be described as "all or nothing" data fetching. Either you had the entire data for your page, or none. - -In the `app` directory, you have additional options to explore: - -1. First, you can use `loading.js` to show an instant loading state from the server while streaming in the result from your data fetching function. -2. Second, you can move data fetching _lower_ in the component tree to only block rendering for the parts of the page that need it. For example, moving data fetching to a specific component rather than fetching it at the root layout. - -Whenever possible, it's best to fetch data in the segment that uses it. This also allows you to show a loading state for only the part of the page that is loading, and not the entire page. - -## Data Fetching without `fetch()` - -You might not always have the ability to use and configure `fetch` requests directly if you're using a third-party library such as an ORM or database client. - -In cases where you cannot use `fetch` but still want to control the caching or revalidating behavior of a layout or page, you can rely on the [default caching behavior](#default-caching-behavior) of the segment or use the [segment cache configuration](#segment-cache-configuration). - -### Default Caching Behavior - -Any data fetching libraries that do not use `fetch` directly **will not** affect caching of a route, and will be static or dynamic depending on the route segment. - -If the segment is static (default), the output of the request will be cached and revalidated (if configured) alongside the rest of the segment. If the segment is dynamic, the output of the request will _not_ be cached and will be re-fetched on every request when the segment is rendered. - -> **Good to know**: Dynamic functions like [`cookies()`](/docs/app/api-reference/functions/cookies) and [`headers()`](/docs/app/api-reference/functions/headers) will make the route segment dynamic. - -### Segment Cache Configuration - -As a temporary solution, until the caching behavior of third-party queries can be configured, you can use [segment configuration](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) to customize the cache behavior of the entire segment. - -```tsx filename="app/page.tsx" switcher -import prisma from './lib/prisma' - -export const revalidate = 3600 // revalidate every hour - -async function getPosts() { - const posts = await prisma.post.findMany() - return posts -} - -export default async function Page() { - const posts = await getPosts() - // ... -} -``` - -```jsx filename="app/page.js" switcher -import prisma from './lib/prisma' - -export const revalidate = 3600 // revalidate every hour - -async function getPosts() { - const posts = await prisma.post.findMany() - return posts -} - -export default async function Page() { - const posts = await getPosts() - // ... -} -``` diff --git a/docs/02-app/01-building-your-application/03-data-fetching/02-caching.mdx b/docs/02-app/01-building-your-application/03-data-fetching/02-caching.mdx deleted file mode 100644 index 9398f124d1632..0000000000000 --- a/docs/02-app/01-building-your-application/03-data-fetching/02-caching.mdx +++ /dev/null @@ -1,288 +0,0 @@ ---- -title: Caching Data -nav_title: Caching -description: Learn about caching routes in Next.js. ---- - -Next.js has built-in support for caching data, both on a per-request basis (recommended) or for an entire route segment. - -Fetch Request Deduplication - -## Per-request Caching - -### `fetch()` - -By default, all `fetch()` requests are cached and deduplicated automatically. This means that if you make the same request twice, the second request will reuse the result from the first request. - -```tsx filename="app/page.tsx" switcher -async function getComments() { - const res = await fetch('https://...') // The result is cached - return res.json() -} - -// This function is called twice, but the result is only fetched once -const comments = await getComments() // cache MISS - -// The second call could be anywhere in your application -const comments = await getComments() // cache HIT -``` - -```jsx filename="app/page.js" switcher -async function getComments() { - const res = await fetch('https://...') // The result is cached - return res.json() -} - -// This function is called twice, but the result is only fetched once -const comments = await getComments() // cache MISS - -// The second call could be anywhere in your application -const comments = await getComments() // cache HIT -``` - -Requests are **not** cached if: - -- Dynamic methods (`next/headers`, `export const POST`, or similar) are used and the fetch is a `POST` request (or uses `Authorization` or `cookie` headers) -- `fetchCache` is configured to skip cache by default -- `revalidate: 0` or `cache: 'no-store'` is configured on individual `fetch` - -Requests made using `fetch` can specify a `revalidate` option to control the revalidation frequency of the request. - -```tsx filename="app/page.tsx" switcher -export default async function Page() { - // revalidate this data every 10 seconds at most - const res = await fetch('https://...', { next: { revalidate: 10 } }) - const data = res.json() - // ... -} -``` - -```jsx filename="app/page.js" switcher -export default async function Page() { - // revalidate this data every 10 seconds at most - const res = await fetch('https://...', { next: { revalidate: 10 } }) - const data = res.json() - // ... -} -``` - -### React `cache()` - -React allows you to [`cache()`](https://github.com/acdlite/rfcs/blob/first-class-promises/text/0000-first-class-support-for-promises.md) and deduplicate requests, memoizing the result of the wrapped function call. The same function called with the same arguments will reuse a cached value instead of re-running the function. - -```ts filename="utils/getUser.ts" switcher -import { cache } from 'react' - -export const getUser = cache(async (id: string) => { - const user = await db.user.findUnique({ id }) - return user -}) -``` - -```js filename="utils/getUser.js" switcher -import { cache } from 'react' - -export const getUser = cache(async (id) => { - const user = await db.user.findUnique({ id }) - return user -}) -``` - -```tsx filename="app/user/[id]/layout.tsx" switcher -import { getUser } from '@utils/getUser' - -export default async function UserLayout({ - params: { id }, -}: { - params: { id: string } -}) { - const user = await getUser(id) - // ... -} -``` - -```jsx filename="app/user/[id]/layout.js" switcher -import { getUser } from '@utils/getUser' - -export default async function UserLayout({ params: { id } }) { - const user = await getUser(id) - // ... -} -``` - -```tsx filename="app/user/[id]/page.tsx" switcher -import { getUser } from '@utils/getUser' - -export default async function Page({ - params: { id }, -}: { - params: { id: string } -}) { - const user = await getUser(id) - // ... -} -``` - -```jsx filename="app/user/[id]/page.js" switcher -import { getUser } from '@utils/getUser' - -export default async function Page({ params: { id } }) { - const user = await getUser(id) - // ... -} -``` - -Although the `getUser()` function is called twice in the example above, only one query will be made to the database. This is because `getUser()` is wrapped in `cache()`, so the second request can reuse the result from the first request. - -> **Good to know**: -> -> - `fetch()` caches requests automatically, so you don't need to wrap functions that use `fetch()` with `cache()`. See [automatic request deduping](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) for more information. -> - In this new model, we recommend **fetching data directly in the component that needs it**, even if you're requesting the same data in multiple components, rather than passing the data between components as props. -> - We recommend using the [`server-only` package](/docs/getting-started/react-essentials#keeping-server-only-code-out-of-client-components-poisoning) to make sure server data fetching functions are never used on the client. - -### `POST` requests and `cache()` - -`POST` requests are automatically deduplicated when using `fetch` – unless they are inside of `POST` Route Handler or come after reading `headers()`/`cookies()`. For example, if you are using GraphQL and `POST` requests in the above cases, you can use `cache` to deduplicate requests. The `cache` arguments must be flat and only include primitives. Deep objects won't match for deduplication. - -```ts filename="utils/getUser.ts" switcher -import { cache } from 'react' - -export const getUser = cache(async (id: string) => { - const res = await fetch('...', { method: 'POST', body: '...' }) - // ... -}) -``` - -```js filename="utils/getUser.js" switcher -import { cache } from 'react' - -export const getUser = cache(async (id) => { - const res = await fetch('...', { method: 'POST', body: '...' }) - // ... -}) -``` - -### Preload pattern with `cache()` - -As a pattern, we suggest optionally exposing a `preload()` export in utilities or components that do data fetching. - -```tsx filename="components/User.tsx" switcher -import { getUser } from '@utils/getUser' - -export const preload = (id: string) => { - // void evaluates the given expression and returns undefined - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void - void getUser(id) -} -export default async function User({ id }: { id: string }) { - const result = await getUser(id) - // ... -} -``` - -```jsx filename="components/User.js" switcher -import { getUser } from '@utils/getUser' - -export const preload = (id) => { - // void evaluates the given expression and returns undefined - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void - void getUser(id) -} -export default async function User({ id }) { - const result = await getUser(id) - // ... -} -``` - -By calling `preload`, you can eagerly start fetching data you're likely going to need. - -```tsx filename="app/user/[id]/page.tsx" switcher -import User, { preload } from '@components/User' - -export default async function Page({ - params: { id }, -}: { - params: { id: string } -}) { - preload(id) // starting loading the user data now - const condition = await fetchCondition() - return condition ? : null -} -``` - -```jsx filename="app/user/[id]/page.js" switcher -import User, { preload } from '@components/User' - -export default async function Page({ params: { id } }) { - preload(id) // starting loading the user data now - const condition = await fetchCondition() - return condition ? : null -} -``` - -> **Good to know**: -> -> - The `preload()` function can have any name. It's a pattern, not an API. -> - This pattern is completely optional and something you can use to optimize on a case-by-case basis. -> This pattern is a further optimization on top of [parallel data fetching](/docs/app/building-your-application/data-fetching/fetching#parallel-data-fetching). Now you don't have to pass promises down as props and can instead rely on the preload pattern. - -### Combining `cache`, `preload`, and `server-only` - -You can combine the `cache` function, the `preload` pattern, and the `server-only` package to create a data fetching utility that can be used throughout your app. - -```ts filename="utils/getUser.ts" switcher -import { cache } from 'react' -import 'server-only' - -export const preload = (id: string) => { - void getUser(id) -} - -export const getUser = cache(async (id: string) => { - // ... -}) -``` - -```js filename="utils/getUser.js" switcher -import { cache } from 'react' -import 'server-only' - -export const preload = (id) => { - void getUser(id) -} - -export const getUser = cache(async (id) => { - // ... -}) -``` - -With this approach, you can eagerly fetch data, cache responses, and guarantee that this data fetching [only happens on the server](/docs/getting-started/react-essentials#keeping-server-only-code-out-of-client-components-poisoning). - -The `getUser.ts` exports can be used by layouts, pages, or components to give them control over when a user's data is fetched. - -## Segment-level Caching - -> **Good to know**: We recommend using per-request caching for improved granularity and control over caching. - -Segment-level caching allows you to cache and revalidate data used in route segments. - -This mechanism allows different segments of a path to control the cache lifetime of the entire route. Each `page.tsx` and `layout.tsx` in the route hierarchy can export a `revalidate` value that sets the revalidation time for the route. - -```tsx filename="app/page.tsx" switcher -export const revalidate = 60 // revalidate this segment every 60 seconds -``` - -```jsx filename="app/page.js" switcher -export const revalidate = 60 // revalidate this segment every 60 seconds -``` - -> **Good to know**: -> -> - If a page, layout, and fetch request inside components all specify a [`revalidate`](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) frequency, the lowest value of the three will be used. -> - Advanced: You can set `fetchCache` to `'only-cache'` or `'force-cache'` to ensure that all `fetch` requests opt into caching but the revalidation frequency might still be lowered by individual `fetch` requests. See [`fetchCache`](/docs/app/api-reference/file-conventions/route-segment-config) for more information. diff --git a/docs/02-app/01-building-your-application/03-data-fetching/03-revalidating.mdx b/docs/02-app/01-building-your-application/03-data-fetching/03-revalidating.mdx deleted file mode 100644 index f2c2a0ca38fc0..0000000000000 --- a/docs/02-app/01-building-your-application/03-data-fetching/03-revalidating.mdx +++ /dev/null @@ -1,103 +0,0 @@ ---- -title: Revalidating Data -nav_title: Revalidating -description: Learn about revalidating data in Next.js using Incremental Static Regeneration. ---- - -Next.js allows you to update specific static routes **without needing to rebuild your entire site**. Revalidation (also known as [Incremental Static Regeneration](/docs/pages/building-your-application/data-fetching/incremental-static-regeneration)) allows you to retain the benefits of static while scaling to millions of pages. - -There are two types of revalidation in Next.js: - -- **Background**: Revalidates the data at a specific time interval. -- **On-demand**: Revalidates the data based on an event such as an update. - -## Background Revalidation - -To revalidate cached data at a specific interval, you can use the `next.revalidate` option in `fetch()` to set the `cache` lifetime of a resource (in seconds). - -```js -fetch('https://...', { next: { revalidate: 60 } }) -``` - -If you want to revalidate data that does not use `fetch` (i.e. using an external package or query builder), you can use the [route segment config](/docs/app/api-reference/file-conventions/route-segment-config#revalidate). - -```tsx filename="app/page.tsx" switcher -export const revalidate = 60 // revalidate this page every 60 seconds -``` - -```jsx filename="app/page.js" switcher -export const revalidate = 60 // revalidate this page every 60 seconds -``` - -In addition to `fetch`, you can also revalidate data using [`cache`](/docs/app/building-your-application/data-fetching/caching#per-request-caching). - -### How it works - -1. When a request is made to the route that was statically rendered at build time, it will initially show the cached data. -2. Any requests to the route after the initial request and before 60 seconds are also cached and instantaneous. -3. After the 60-second window, the next request will still show the cached (stale) data. -4. Next.js will trigger a regeneration of the data in the background. -5. Once the route generates successfully, Next.js will invalidate the cache and show the updated route. If the background regeneration fails, the old data would still be unaltered. - -When a request is made to a route segment that hasn’t been generated, Next.js will dynamically render the route on the first request. Future requests will serve the static route segments from the cache. - -> **Good to know**: Check if your upstream data provider has caching enabled by default. You might need to disable (e.g. `useCdn: false`), otherwise a revalidation won't be able to pull fresh data to update the ISR cache. Caching can occur at a CDN (for an endpoint being requested) when it returns the `Cache-Control` header. ISR on Vercel [persists the cache globally and handles rollbacks](https://vercel.com/docs/concepts/incremental-static-regeneration/overview). - -## On-demand Revalidation - -If you set a `revalidate` time of `60`, all visitors will see the same generated version of your site for one minute. The only way to invalidate the cache is if someone visits the page after the minute has passed. - -The Next.js App Router supports revalidating content on-demand based on a route or cache tag. This allows you to manually purge the Next.js cache for specific fetches, making it easier to update your site when: - -- Content from your headless CMS is created or updated. -- Ecommerce metadata changes (price, description, category, reviews, etc). - -### Using On-Demand Revalidation - -Data can be revalidated on-demand by path ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)). - -For example, the following `fetch` adds the cache tag `collection`: - -```tsx filename="app/page.tsx" switcher -export default async function Page() { - const res = await fetch('https://...', { next: { tags: ['collection'] } }) - const data = await res.json() - // ... -} -``` - -```jsx filename="app/page.js" switcher -export default async function Page() { - const res = await fetch('https://...', { next: { tags: ['collection'] } }) - const data = await res.json() - // ... -} -``` - -This cached data can then be revalidated on-demand by calling `revalidateTag` in a [Route Handler](/docs/app/building-your-application/routing/router-handlers). - -```ts filename="app/api/revalidate/route.ts" switcher -import { NextRequest, NextResponse } from 'next/server' -import { revalidateTag } from 'next/cache' - -export async function GET(request: NextRequest) { - const tag = request.nextUrl.searchParams.get('tag') - revalidateTag(tag) - return NextResponse.json({ revalidated: true, now: Date.now() }) -} -``` - -```js filename="app/api/revalidate/route.js" switcher -import { NextResponse } from 'next/server' -import { revalidateTag } from 'next/cache' - -export async function GET(request) { - const tag = request.nextUrl.searchParams.get('tag') - revalidateTag(tag) - return NextResponse.json({ revalidated: true, now: Date.now() }) -} -``` - -## Error Handling and Revalidation - -If an error is thrown while attempting to revalidate data, the last successfully generated data will continue to be served from the cache. On the next subsequent request, Next.js will retry revalidating the data. diff --git a/docs/02-app/01-building-your-application/03-data-fetching/index.mdx b/docs/02-app/01-building-your-application/03-data-fetching/index.mdx deleted file mode 100644 index cbfabbdfa9522..0000000000000 --- a/docs/02-app/01-building-your-application/03-data-fetching/index.mdx +++ /dev/null @@ -1,163 +0,0 @@ ---- -title: Data Fetching -description: Learn the fundamentals of data fetching with React and Next.js. ---- - -The Next.js App Router introduces a new, simplified data fetching system built on React and the Web platform. This page will go through the fundamental concepts and patterns to help you manage your data's lifecycle. - -Here's a quick overview of the recommendations on this page: - -1. [Fetch data on the server](#fetching-data-on-the-server) using Server Components. -2. [Fetch data in parallel](#parallel-and-sequential-data-fetching) to minimize waterfalls and reduce loading times. -3. For Layouts and Pages, [fetch data where it's used](#automatic-fetch-request-deduping). Next.js will automatically dedupe requests in a tree. -4. Use [Loading UI, Streaming and Suspense](#streaming-and-suspense) to progressively render a page and show a result to the user while the rest of the content loads. - -## The `fetch()` API - -The new data fetching system is built on top of the native [`fetch()` Web API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) and makes use of `async` and `await` in Server Components. - -- React extends `fetch` to provide [automatic request deduping](#automatic-fetch-request-deduping). -- Next.js extends the `fetch` options object to allow each request to set its own [caching and revalidating](/docs/app/building-your-application/data-fetching/caching) rules. - -[Learn how to use `fetch` in Next.js](/docs/app/building-your-application/data-fetching/fetching). - -## Fetching Data on the Server - -Whenever possible, we recommend fetching data in [Server Components](/docs/getting-started/react-essentials#server-components). Server Components **always fetch data on the server**. This allows you to: - -- Have direct access to backend data resources (e.g. databases). -- Keep your application more secure by preventing sensitive information, such as access tokens and API keys, from being exposed to the client. -- Fetch data and render in the same environment. This reduces both the back-and-forth communication between client and server, as well as the work on the main thread on the client. -- Perform multiple data fetches with single round-trip instead of multiple individual requests on the client. -- Reduce client-server [waterfalls](#parallel-and-sequential-data-fetching). -- Depending on your region, data fetching can also happen closer to your data source, reducing latency and improving performance. - -> **Good to know**: It's still possible to fetch data client-side. We recommend using a third-party library such as [SWR](https://swr.vercel.app/) or [React Query](https://tanstack.com/query/v4/) with Client Components. In the future, it'll also be possible to fetch data in Client Components using React's [`use()` hook](/docs/app/building-your-application/data-fetching/fetching#use-in-client-components). - -## Fetching Data at the Component Level - -In the App Router, you can fetch data inside [layouts](/docs/app/building-your-application/routing/pages-and-layouts#layouts), [pages](/docs/app/building-your-application/routing/pages-and-layouts#pages), and components. Data fetching is also compatible with [Streaming and Suspense](#streaming-and-suspense). - -> **Good to know**: For layouts, it's not possible to pass data between a parent layout and its `children` components. We recommend **fetching data directly inside the layout that needs it**, even if you're requesting the same data multiple times in a route. Behind the scenes, React and Next.js will [cache and dedupe](#automatic-fetch-request-deduping) requests to avoid the same data being fetched more than once. - -## Parallel and Sequential Data Fetching - -When fetching data inside components, you need to be aware of two data fetching patterns: Parallel and Sequential. - -Sequential and Parallel Data Fetching - -- With **parallel data fetching**, requests in a route are eagerly initiated and will load data at the same time. This reduces client-server waterfalls and the total time it takes to load data. -- With **sequential data fetching**, requests in a route are dependent on each other and create waterfalls. There may be cases where you want this pattern because one fetch depends on the result of the other, or you want a condition to be satisfied before the next fetch to save resources. However, this behavior can also be unintentional and lead to longer loading times. - -[Learn how to implement parallel and sequential data fetching](/docs/app/building-your-application/data-fetching/fetching#data-fetching-patterns). - -## Automatic `fetch()` Request Deduping - -If you need to fetch the same data (e.g. current user) in multiple components in a tree, Next.js will automatically cache `fetch` requests (`GET`) that have the same input in a temporary cache. This optimization prevents the same data from being fetched more than once during a rendering pass. - -Fetch Request Deduplication - -- On the server, the cache lasts the lifetime of a server request until the rendering process completes. - - This optimization applies to `fetch` requests made in Layouts, Pages, Server Components, `generateMetadata` and `generateStaticParams`. - - This optimization also applies during [static generation](/docs/app/building-your-application/rendering#static-rendering). -- On the client, the cache lasts the duration of a session (which could include multiple client-side re-renders) before a full page reload. - -> **Good to know**: -> -> - `fetch` requests are automatically deduplicated [under the following conditions](/docs/app/building-your-application/data-fetching/caching). -> - If you're unable to use `fetch`, React provides a [`cache` function](/docs/app/building-your-application/data-fetching/caching#react-cache) to allow you to manually cache data for the duration of the request. - -## Static and Dynamic Data Fetching - -There are two types of data: **Static** and **Dynamic**. - -- **Static Data** is data that doesn't change often. For example, a blog post. -- **Dynamic Data** is data that changes often or can be specific to users. For example, a shopping cart list. - -Dynamic and Static Data Fetching - -By default, Next.js automatically does static fetches. This means that the data will be fetched at build time, cached, and reused on each request. As a developer, you have control over how the static data is [cached](#caching-data) and [revalidated](#revalidating-data). - -There are two benefits to using static data: - -1. It reduces the load on your database by minimizing the number of requests made. -2. The data is automatically cached for improved loading performance. - -However, if your data is personalized to the user or you want to always fetch the latest data, you can mark requests as _dynamic_ and fetch data on each request without caching. - -[Learn how to do Static and Dynamic data fetching](/docs/app/building-your-application/data-fetching/fetching#static-data-fetching). - -## Caching Data - -Caching is the process of storing data in a location (e.g. [Content Delivery Network](https://vercel.com/docs/concepts/edge-network/overview)) so it doesn't need to be re-fetched from the original source on each request. - -Static Site Generation - -The **Next.js Cache** is a persistent [HTTP cache](https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching) that can be globally distributed. This means the cache can scale automatically and be shared across multiple regions depending on your platform (e.g. [Vercel](https://vercel.com/docs/concepts/next.js/overview)). - -Next.js extends the [options object](https://developer.mozilla.org/en-US/docs/Web/API/fetch#:~:text=preflight%20requests.-,cache,-A%20string%20indicating) of the `fetch()` function to allow each request on the server to set its own persistent caching behavior. Together with [component-level data fetching](#fetching-data-at-the-component-level), this allows you to configure caching within your application code directly where the data is being used. - -During server rendering, when Next.js comes across a fetch, it will check the cache to see if the data is already available. If it is, it will return the cached data. If not, it will fetch and store data for future requests. - -> **Good to know**: If you're unable to use `fetch`, React provides a [`cache` function](/docs/app/building-your-application/data-fetching/caching#react-cache) to allow you to manually cache data for the duration of the request. - -[Learn more about caching in Next.js](/docs/app/building-your-application/data-fetching/caching). - -### Revalidating Data - -Revalidation is the process of purging the cache and re-fetching the latest data. This is useful when your data changes and you want to ensure your application shows the latest version without having to rebuild your entire application. - -Next.js provides two types of revalidation: - -- [**Background**](/docs/app/building-your-application/data-fetching/revalidating#background-revalidation): Revalidates the data at a specific time interval. -- [**On-demand**](/docs/app/building-your-application/data-fetching/revalidating#on-demand-revalidation): Revalidates the data whenever there is an update. - -[Learn how to revalidate data](/docs/app/building-your-application/data-fetching/revalidating). - -### Streaming and Suspense - -Streaming and [Suspense](https://react.dev/reference/react/Suspense) are new React features that allow you to progressively render and incrementally stream rendered units of the UI to the client. - -With Server Components and [nested layouts](/docs/app/building-your-application/routing/pages-and-layouts), you're able to instantly render parts of the page that do not specifically require data, and show a [loading state](/docs/app/building-your-application/routing/loading-ui-and-streaming) for parts of the page that are fetching data. This means the user does not have to wait for the entire page to load before they can start interacting with it. - -Server Rendering with Streaming - -To learn more about Streaming and Suspense, see the [Loading UI](/docs/app/building-your-application/routing/loading-ui-and-streaming) and [Streaming and Suspense](/docs/app/building-your-application/routing/loading-ui-and-streaming#streaming-with-suspense) pages. - -## Old Methods - -Previous Next.js data fetching methods such as [`getServerSideProps`](/docs/pages/building-your-application/data-fetching/get-server-side-props), [`getStaticProps`](/docs/pages/building-your-application/data-fetching/get-static-props), and [`getInitialProps`](/docs/pages/api-reference/functions/get-initial-props) are **not** supported in the new App Router. However, you can still use them in the [Pages Router](/docs/pages/building-your-application/data-fetching). - -## Next Steps - -Now that you understand the fundamentals of data fetching in Next.js, you can learn more about managing data in your application: diff --git a/docs/02-app/01-building-your-application/03-rendering/01-static-and-dynamic.mdx b/docs/02-app/01-building-your-application/03-rendering/01-static-and-dynamic.mdx new file mode 100644 index 0000000000000..e83353fb2e115 --- /dev/null +++ b/docs/02-app/01-building-your-application/03-rendering/01-static-and-dynamic.mdx @@ -0,0 +1,44 @@ +--- +title: Static and Dynamic Rendering +nav_title: Static and Dynamic +description: Learn about static and dynamic rendering in Next.js. +related: + description: Learn how Next.js caches data and the result of static rendering. + links: + - app/building-your-application/caching +--- + +In Next.js, a route can be statically or dynamically rendered. + +## Static Rendering (Default) + +By default, Next.js statically renders routes to improve performance. At **build time**, Server and Client components are rendered on the server, and the result of the work is [cached](/docs/app/building-your-application/caching#full-route-cache) and reused on subsequent requests. + +> To understand how Client and Server Components are rendered, see the [Rendering Client and Server Components](/docs/app/building-your-application/rendering/server-and-client-components) page. + +## Dynamic Rendering + +With Dynamic Rendering, both Server _and_ Client Components for a route are rendered on the server at **request time**. + +During rendering, if a [dynamic function](#dynamic-functions) or uncached data request is discovered, Next.js will switch to dynamically rendering the whole route. This table summarizes how dynamic functions and data caching affect whether a route is statically or dynamically rendered: + +| Route | Dynamic Functions | Data | +| -------------------- | ----------------- | ---------- | +| Statically Rendered | No | Cached | +| Dynamically Rendered | Yes | Cached | +| Dynamic Rendered | No | Not Cached | +| Dynamic Rendered | Yes | Not Cached | + +From the table above, for a route to be fully static, all data must be cached. However, you can have a dynamically rendered route that uses both cached and uncached data fetches. This is useful when you have a page that mostly re-uses cached data, but has some uncached data. It allows you to opt into dynamic rendering without worrying about the performance impact of fetching all the data at request time. + +> **Good to know**: In the future, Next.js will introduce hybrid server-side rendering where layouts and pages in a route can be independently statically or dynamically rendered, instead of the whole route. + +### Dynamic Functions + +Dynamic functions rely on information that can only be known at request time such as a user's cookies, current requests headers, or the URL's search params. In Next.js, these dynamic functions are: + +- **[`cookies()`](/docs/app/api-reference/functions/cookies) and [`headers()`](/docs/app/api-reference/functions/headers)**: Using these in a Server Component will opt the whole route into dynamic rendering at request time. +- **[`useSearchParams()`](/docs/app/api-reference/functions/use-search-params)**: + - In Client Components, it'll skip static rendering and instead render all Client Components up to the nearest parent Suspense boundary on the client. + - We recommend wrapping the Client Component that uses `useSearchParams()` in a `` boundary. This will allow any Client Components above it to be statically rendered. [Example](/docs/app/api-reference/functions/use-search-params#static-rendering). +- **[`searchParams`](/docs/app/api-reference/file-conventions/page#searchparams-optional)**: Using the [Pages](/docs/app/api-reference/file-conventions/page) prop will opt the page into dynamic rendering at request time. diff --git a/docs/02-app/01-building-your-application/03-rendering/02-server-and-client-components.mdx b/docs/02-app/01-building-your-application/03-rendering/02-server-and-client-components.mdx new file mode 100644 index 0000000000000..894caa5c6ab7a --- /dev/null +++ b/docs/02-app/01-building-your-application/03-rendering/02-server-and-client-components.mdx @@ -0,0 +1,7 @@ +--- +title: Rendering Client and Server Components +nav_title: Client and Server Components +description: Learn how Server and Client Components are rendered in Next.js. +--- + +This page is currently being worked on. Follow its progress and give feedback on [GitHub](https://github.com/vercel/next.js/pull/51579). diff --git a/docs/02-app/01-building-your-application/02-rendering/02-edge-and-nodejs-runtimes.mdx b/docs/02-app/01-building-your-application/03-rendering/03-edge-and-nodejs-runtimes.mdx similarity index 88% rename from docs/02-app/01-building-your-application/02-rendering/02-edge-and-nodejs-runtimes.mdx rename to docs/02-app/01-building-your-application/03-rendering/03-edge-and-nodejs-runtimes.mdx index 373fe9739d612..fdd358802ae3e 100644 --- a/docs/02-app/01-building-your-application/02-rendering/02-edge-and-nodejs-runtimes.mdx +++ b/docs/02-app/01-building-your-application/03-rendering/03-edge-and-nodejs-runtimes.mdx @@ -5,14 +5,12 @@ description: Learn about the switchable runtimes (Edge and Node.js) in Next.js. {/* The content of this doc is shared between the app and pages router. You can use the `Content` component to add content that is specific to the Pages Router. Any shared content should not be wrapped in a component. */} -In the context of Next.js, "runtime" refers to the set of libraries, APIs, and general functionality available to your code during execution. +In the context of Next.js, runtime refers to the set of libraries, APIs, and general functionality available to your code during execution. -Next.js has two server runtimes where you can render parts of your application code: +On the server, there are two runtimes where parts of your application code can be rendered: -- [Node.js Runtime](#nodejs-runtime) -- [Edge Runtime](#edge-runtime) - -Each runtime has its own set of APIs. Please refer to the [Node.js Docs](https://nodejs.org/docs/latest/api/) and [Edge Docs](/docs/app/api-reference/edge) for the full list of available APIs. Both runtimes can also support [streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) depending on your deployment infrastructure. +- The **Node.js Runtime** (default) has access to all Node.js APIs and compatible packages from the ecosystem. +- The **Edge Runtime** is based on [Web APIs](/docs/app/api-reference/edge). By default, the `app` directory uses the Node.js runtime. However, you can opt into different runtimes (e.g. Edge) on a per-route basis. @@ -81,3 +79,5 @@ export const runtime = 'edge' // 'nodejs' (default) | 'edge' If the segment runtime is _not_ set, the default `nodejs` runtime will be used. You do not need to use the `runtime` option if you do not plan to change from the Node.js runtime. + +> Please refer to the [Node.js Docs](https://nodejs.org/docs/latest/api/) and [Edge Docs](/docs/app/api-reference/edge) for the full list of available APIs. Both runtimes can also support [streaming](/docs/app/building-your-application/routing/loading-ui-and-streaming) depending on your deployment infrastructure. diff --git a/docs/02-app/01-building-your-application/03-rendering/index.mdx b/docs/02-app/01-building-your-application/03-rendering/index.mdx new file mode 100644 index 0000000000000..81bad5fc67e80 --- /dev/null +++ b/docs/02-app/01-building-your-application/03-rendering/index.mdx @@ -0,0 +1,29 @@ +--- +title: Rendering +description: Learn the differences between Next.js rendering environments, strategies, and runtimes. +--- + +Rendering converts the code you write into user interfaces. This section will help you understand the differences between rendering environments, Client and Server Component rendering, static and dynamic rendering, and runtimes. + +## Background + +There are two environments where web applications can be rendered: the client and the server. + +Client and Server Environments + +- The **client** refers to the browser on a user's device that sends a request to a server for your application code. It then turns the response from the server into an interface the user can interact with. +- The **server** refers to the computer in a data center that stores your application code, receives requests from a client, does some computation, and sends back an appropriate response. + +Before React 18, the primary way to render your application was entirely on the client. Next.js provided an easier way to break down your application into **pages** and render on the server. + +Now, with Server and Client Components, **React renders on the client and the server**, meaning you can choose where to render your application code, per component. + +By default, the App Router uses Server Components to improve performance, and you can opt into using Client Components when needed. + +Learn more about rendering by exploring the sections below: diff --git a/docs/02-app/01-building-your-application/04-caching/index.mdx b/docs/02-app/01-building-your-application/04-caching/index.mdx new file mode 100644 index 0000000000000..75f895651b5e3 --- /dev/null +++ b/docs/02-app/01-building-your-application/04-caching/index.mdx @@ -0,0 +1,589 @@ +--- +title: Caching in Next.js +nav_title: Caching +description: An overview of caching mechanisms in Next.js. +--- + +Next.js improves your application's performance and reduce costs by caching rendering work and data requests. This page provides an in-depth look at Next.js caching mechanisms, the APIs you can use to configure them, and how they interact with each other. + +> **Good to know**: This page helps you understand how Next.js works under the hood but is **not** essential knowledge to be productive with Next.js. Most of Next.js' caching heuristics are determined by your API usage and have defaults for the best performance with zero or minimal configuration. + +## Overview + +Here's a high-level overview of the different caching mechanisms and their purpose: + +| Mechanism | What | Where | Purpose | Duration | +| ------------------------------------------- | -------------------------- | ------ | ----------------------------------------------- | ------------------------------- | +| [Request Memoization](#request-memoization) | Return values of functions | Server | Re-use data in a React Component tree | Per-request lifecycle | +| [Data Cache](#data-cache) | Data | Server | Store data across user requests and deployments | Persistent (can be revalidated) | +| [Full Route Cache](#full-route-cache) | HTML and RSC payload | Server | Reduce rendering cost and improve performance | Persistent (can be revalidated) | +| [Router Cache](#router-cache) | RSC Payload | Client | Reduce server requests on navigation | User session or time-based | + +By default, Next.js will cache as much as possible to improve performance and reduce cost. This means routes are statically rendered and data requests are cached unless you opt out. The diagram below shows the default caching behavior; at build time and when a route is first visited. + +Diagram showing the default caching behavior in Next.js for the four mechanisms, with HIT, MISS and SET at build time and when a route is first visited. + +This behavior changes depending on whether the route is statically or dynamically rendered, data is cached or uncached, and whether it's the initial visit or a subsequent navigation. Depending on your use case, you can configure the caching behavior for individual routes and data requests. + +## Request Memoization + +React extends the [`fetch` API](#fetch) to automatically **memoize** requests that have the same URL and options. This means you can call a fetch function for the same data in multiple places in a React component tree while only executing it once. + +Deduplicated Fetch Requests + +For example, if you need to use the same data across a route (e.g. in a Layout, Page, and multiple components), you do not have to fetch data at the top of the tree then forward props between components. Instead, you can fetch data in the components that need it without worrying about the performance implications of making multiple requests across the network for the same data. + +```tsx filename="app/example.tsx" switcher +async function getItem() { + // The `fetch` function is automatically memoized and the result is cached + const res = await fetch('https://.../item/1') + return res.json() +} + +// This function is called twice, but only executed the first time +const item = await getItem() // cache MISS + +// The second call could be anywhere in your route +const item = await getItem() // cache HIT +``` + +```jsx filename="app/example.js" switcher +async function getItem() { + // The `fetch` function is automatically memoized and the result is cached + const res = await fetch('https://.../item/1') + return res.json() +} + +// This function is called twice, but only executed the first time +const item = await getItem() // cache MISS + +// The second call could be anywhere in your route +const item = await getItem() // cache HIT +``` + +Diagram showing how fetch memoization works during React rendering. + +The first time the request is called, it'll be a cache `MISS`, the function will be executed, and the data will be fetched from the Next.js [Data Cache](#data-cache) or your data store and the result will be stored in memory. Subsequent function calls will be a cache `HIT`, and the data will be returned from memory without executing the function. + +> **Good to know**: +> +> - Request memoization is a React feature, not a Next.js feature. It's included here to show how it interacts with the other caching mechanisms. +> - Memoization only applies to the `GET` method in `fetch` requests. +> - Memoization only applies to the React Component tree, this means: +> - It applies to `fetch` requests in `generateMetadata`, `generateStaticParams`, Layouts, Pages, and other Server Components. +> - It doesn't apply to `fetch` requests in Route Handlers as they are not a part of the React component tree. +> - For cases where `fetch` is not suitable (e.g. database clients, CMS clients, or GraphQL), you can use the [React `cache` function](#react-cache-function) to memoize functions. + +### Duration + +The cache lasts the lifetime of a server request until the React component tree has finished rendering. + +### Revalidating + +Since the memoization is not shared across server requests and only applies during rendering, there is no need to revalidate it. + +### Opting out + +To opt out of memoization in `fetch` requests, you can pass an `AbortController` `signal` to the request. + +```js +const { signal } = new AbortController() +fetch(url, { signal }) +``` + +## Data Cache + +Next.js has a built-in Data Cache that **persists** the result of data fetches across incoming **server requests** and **deployments**. This is possible because Next.js extends the native `fetch` API to allow each request on the server to set its own persistent caching semantics. + +By default, data requests that use `fetch` are **cached**. You can use the [`cache`](#fetch-optionscache) and [`next.revalidate`](#fetch-optionsnextrevalidate) options of `fetch` to configure the caching behavior. + +> **Good to know**: In the browser, the `cache` option of `fetch` indicates how a request will interact with the browser's HTTP cache, with Next.js, the `cache` option indicates how a server-side request will interact with the servers Data Cache. + +Diagram showing how cached and uncached fetch requests interact with the Data Cache. Cached requests are stored in the Data Cache, and memoized, uncached requests are fetched from the data source, not stored in the Data Cache, and memoized. + +The first time a `fetch` request is called during rendering, Next.js checks the Data Cache for a cached response. If a cached response is found, it's returned immediately and [memoized](#request-memoization). If not, the request is made to the data source, the result is stored in the Data Cache, and memoized. + +For uncached data (e.g. `{ cache: 'no-store' }`), the result is always fetched from the data source, and memoized. + +Whether the data is cached or uncached, the requests are always memoized to avoid making duplicate requests for the same data during a React render pass. + +> **Differences between the Data Cache and Request Memoization** +> +> While both caching mechanisms help improve performance by re-using cached data, the Data Cache is persistent across incoming requests and deployments, whereas memoization only lasts the lifetime of a request. +> +> With memoization, we reduce the number of **duplicate** requests in the same render pass that have to cross the network boundary from the rendering server to the Data Cache server (e.g. a CDN or Edge Network) or data source (e.g. a database or CMS). With the Data Cache, we reduce the number of requests made to our origin data source. + +### Duration + +The Data Cache is persistent across incoming requests and deployments unless you revalidate or opt-out. + +### Revalidating + +Cached data can be revalidated in two ways, with: + +- **Time-based Revalidation**: Revalidate data after a certain amount of time has passed and a new request is made. This is useful for data that changes infrequently and freshness is not as critical. +- **On-demand Revalidation:** Revalidate data based on an event (e.g. form submission). On-demand revalidation can use a tag-based or path-based approach to revalidate groups of data at once. This is useful when you want to ensure the latest data is shown as soon as possible (e.g. when content from your headless CMS is updated). + +#### Time-based Revalidation + +To revalidate data at a timed interval, you can use the `next.revalidate` option of `fetch` to set the cache lifetime of a resource (in seconds). + +```js +// Revalidate at most every hour +fetch('https://...', { next: { revalidate: 3600 } }) +``` + +Alternatively, you can use [Route Segment Config options](#segment-config-options) to configure all `fetch` requests in a segment or for cases where you're not able to use `fetch`. + +**How Time-based Revalidation Works**: + +Diagram showing how time-based revalidation works, after the revalidation period, stale data is returned for the first request, then data is revalidated. + +1. The first time a fetch request with `revalidate` is called, the data will be fetched from the external data source and stored in the Data Cache. +2. Any requests that are called within the specified timeframe (e.g. 60-seconds) will return the cached data. +3. After the timeframe, the next request will still return the cached (now stale) data. + - Next.js will trigger a revalidation of the data in the background. + - Once the data is fetched successfully, Next.js will update the Data Cache with the fresh data. + - If the background revalidation fails, the previous data will be kept unaltered. + +This is similar to [**stale-while-revalidate**](https://web.dev/stale-while-revalidate/) behavior. + +#### On-demand Revalidation + +Data can be revalidated on-demand by path ([`revalidatePath`](#revalidatepath)) or by cache tag ([`revalidateTag`](#fetch-optionsnexttag-and-revalidatetag)). + +**How On-Demand Revalidation Works**: + +Diagram showing how on-demand revalidation works, the Data Cache is updated with fresh data after a revalidation request. + +On-demand revalidation purges entries from the Data Cache. When the request is executed again, it'll be a cache `MISS`, and the Data Cache will be populated with fresh data. This is different from time-based revalidation, which keeps the stale data in the cache until the fresh data is fetched. + +### Opting out + +For individual data fetches, you can opt out of caching by setting the [`cache`](#fetch-optionscache) option to `no-store`. This means data will be fetched whenever `fetch` is called. + +```jsx +// Opt out of caching for an individual `fetch` request +fetch(`https://...`, { cache: 'no-store' }) +``` + +Alternatively, you can also use the [Route Segment Config options](#segment-config-options) to opt out of caching for a specific route segment. This will affect all data requests in the route segment, including third-party libraries. + +```jsx +// Opt out of caching for all data requests in the route segment +export const dynamic = 'force-dynamic' +``` + +> **Vercel Data Cache** +> +> If your Next.js application is deployed to Vercel, we recommend reading the [Vercel Data Cache](https://vercel.com/docs/infrastructure/data-cache) documentation for a better understanding of Vercel specific features. + +## Full Route Cache + +Next.js automatically renders and caches routes at build time. This is an optimization that allows you to serve the cached route instead of rendering on the server for every request, resulting in faster page loads. + +> **Related terms**: +> +> - You may see the terms **Automatic Static Optimization**, **Static Site Generation**, or **Static Rendering** being used interchangeably to refer to the process of rendering and caching routes of your application at build time. + +To understand how the Full Route Cache works, it's helpful to look at how React handles rendering, and how Next.js caches the result: + +### 1. React Rendering on the Server + +On the server, Next.js uses React's APIs to orchestrate rendering. The rendering work split into chunks, by individual routes segments and Suspense boundaries. + +Each chunk is rendered in two steps: + +1. React renders Server Components into a special data format, optimized for streaming, called the **React Server Component Payload**. +2. Next.js uses the React Server Component Payload and Client Component JavaScript instructions to render **HTML** on the server. + +This means we don't have to wait for everything to render before caching the work or sending a response. Instead, we can stream a response as work is completed. + +> **What is the React Server Component Payload?** +> +> The React Server Component Payload is a compact binary representation of the rendered React Server Components tree. It's used by React on the client to update the browser's DOM. The React Server Component Payload contains: +> +> - The rendered result of Server Components +> - Placeholders for where Client Components should be rendered and references to their JavaScript files +> - Any props passed from a Server Component to a Client Component +> +> To learn more, see the [React Rendering](/docs/app/building-your-application/rendering/server-and-client-components) documentation. + +### 2. Next.js Caching on the Server (Full Route Cache) + +Default behavior of the Full Route Cache, showing how the React Server Component Payload and HTML are cached on the server for statically rendered routes. + +The default behavior of Next.js is to cache the rendered result (React Server Component Payload and HTML) of a route on the server. This applies to statically rendered routes at build time, or during revalidation. + +### 3. React Hydration and Reconciliation on the Client + +At request time, on the client: + +1. The HTML is used to immediately show a fast non-interactive initial preview of the Client and Server Components. +2. The React Server Components Payload is used to reconcile the Client and rendered Server Component trees, and update the DOM. +3. The JavaScript instructions are used to [hydrate](https://react.dev/reference/react-dom/client/hydrateRoot) Client Components and make the application interactive. + +### 4. Next.js Caching on the Client (Router Cache) + +The React Server Component Payload is stored in the client-side [Router Cache](#router-cache) - a separate in-memory cache, split by individual route segment. This Router Cache is used to improve the navigation experience by storing previously visited routes and prefetching future routes. + +### 5. Subsequent Navigations + +On subsequent navigations or during prefetching, Next.js will check if the React Server Components Payload is stored in Router Cache. If so, it will skip sending a new request to the server. + +If the route segments are not in the cache, Next.js will fetch the React Server Components Payload from the server, and populate the Router Cache on the client. + +### Static and Dynamic Rendering + +Whether a route is cached or not at build time depends on whether it's statically or dynamically rendered. Static routes are cached by default, whereas dynamic routes are rendered at request time, and not cached. + +This diagram shows the difference between statically and dynamically rendered routes, with cached and uncached data: + +How static and dynamic rendering affects the Full Route Cache. Static routes are cached at build time or after data revalidation, whereas dynamic routes are never cached + +Learn more about [static and dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic). + +### Duration + +By default, the Full Route Cache is persistent. This means that the render output is cached across user requests. + +### Invalidation + +There are two ways you can invalidate the Full Route Cache: + +- **[Revalidating Data](/docs/app/building-your-application/caching#revalidating)**: Revalidating the [Data Cache](#data-cache), will in turn invalidate the Router Cache by re-rendering components on the server and caching the new render output. +- **Redeploying**: Unlike the Data Cache, which persists across deployments, the Full Route Cache is cleared on new deployments. + +### Opting out + +You can opt out of the Full Route Cache, or in other words, dynamically render components for every incoming request, by: + +- **Using a [Dynamic Function](#dynamic-functions)**: This will opt the route out from the Full Route Cache and dynamically render it at request time. The Data Cache can still be used. +- **Using the route segment config options `export const dynamic = 'force-dynamic'` or `export const revalidate = 0`**: This will skip the Full Route Cache and the Data Cache. Meaning components will be rendered and data fetched on every incoming request to the server. The Router Cache will still apply as it's a client-side cache. +- **Opting out of the [Data Cache](#data-cache)**: If a route has a `fetch` request that is not cached, this will opt the route out of the Full Route Cache. The data for the specific `fetch` request will be fetched for every incoming request. Other `fetch` requests that do not opt out of caching will still be cached in the Data Cache. This allows for a hybrid of cached and uncached data. + +## Router Cache + +Next.js has an in-memory client-side cache that stores the React Server Component Payload, split by individual route segments, for the duration of a user session. This is called the Router Cache. + +How the Router cache works for static and dynamic routes, showing MISS and HIT for initial and subsequent navigations. + +As users navigates between routes, Next.js caches visited route segments and [prefetches](/docs/app/building-your-application/routing/linking-and-navigating#1-prefetching) the routes the user is likely to navigate to (based on `` components in their viewport). + +This results in an improved navigation experience for the user: + +- Instant backward/forward navigation because visited routes are cached and fast navigation to new routes because of prefetching and [partial rendering](/docs/app/building-your-application/routing/linking-and-navigating#3-partial-rendering). +- No full-page reload between navigations and React state and browser state is preserved. + +> **Difference between the Router Cache and Full Route Cache**: +> +> The Router Cache temporarily stores the React Server Component Payload in the browser for the duration of a user session, whereas the Full Route Cache persistently stores the React Server Component Payload and HTML on the server across multiple user requests. + +> While the Full Route Cache only caches statically rendered routes, the Router Cache applies to both statically and dynamically rendered routes. + +> **Related Terms:** +> +> You may see the Router Cache being referred to as **Client-side Cache** or **Prefetch Cache**. While **Prefetch Cache** refers to the prefetched route segments, **Client-side Cache** refers to the whole Router cache, which includes both visited and prefetched segments. +> This cache specifically applies to Next.js and Server Components, and is different to the browser's [bfcache](https://web.dev/bfcache/), though it has a similar result. + +### Duration + +The cache is stored in the browser's temporary memory. Two factors determine how long the router cache lasts: + +- **Session**: The cache persists across navigation. However, it's cleared on page refresh. +- **Automatic Invalidation Period**: The cache of an individual segment is automatically invalidated after a specific time. The duration depends on whether the route is [statically](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default) or [dynamically](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering) rendered: + - **Dynamically Rendered**: 30 seconds + - **Statically Rendered**: 5 minutes + +While a page refresh will clear **all** cached segments, the automatic invalidation period only affects the individual segment from the time it was last accessed or created. + +By adding `prefetch={true}` or calling `router.prefetch` for a dynamically rendered route, you can opt into caching for 5 minutes. + +### Invalidation + +There are two ways you can invalidate the Router Cache: + +- In a **Server Action**: + - Revalidating data on-demand by path with ([`revalidatePath`](/docs/app/api-reference/functions/revalidatePath)) or by cache tag with ([`revalidateTag`](/docs/app/api-reference/functions/revalidateTag)) + - Using [`cookies.set`](/docs/app/api-reference/functions/cookies#cookiessetname-value-options) or [`cookies.delete`](/docs/app/api-reference/functions/cookies#deleting-cookies) invalidates the Router Cache to prevent routes that use cookies from becoming stale (e.g. authentication). +- Calling [`router.refresh`](/docs/app/api-reference/functions/use-router) will invalidate the Router Cache and make a new request to the server for the current route. + +### Opting out + +It's not possible to opt out of the Router Cache. + +You can opt out of **prefetching** by setting the `prefetch` prop of the `` component to `false`. However, this will still temporarily store the route segments for 30s to allow instant navigation between nested segments, such as tab bars, or back and forward navigation. Visited routes will still be cached. + +## Cache Interactions + +When configuring the different caching mechanisms, it's important to understand how they interact with each other: + +### Data Cache and Full Route Cache + +- Revalidating or opting out of the Data Cache **will** invalidate the Full Route Cache, as the render output depends on data. +- Invalidating or opting out of the Full Route Cache **does not** affect the Data Cache. You can dynamically render a route that has both cached and uncached data. This is useful when most of your page uses cached data, but you have a few components that rely on data that needs to be fetched at request time. You can dynamically render without worrying about the performance impact of re-fetching all the data. + +### Data Cache and Client-side Router cache + +- Revalidating the Data Cache in a [Route Handler](/docs/app/building-your-application/routing/route-handlers) **will not** immediately invalidate the Router Cache as the Router Handler isn't tied to a specific route. This means Router Cache will continue to serve the previous payload until a hard refresh, or the automatic invalidation period has elapsed. +- To immediately invalidate the Data Cache and Router cache, you can use [`revalidatePath`](#revalidatepath) or [`revalidateTag`](#fetch-optionsnexttag-and-revalidatetag) in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions). + +## APIs + +The following table provides an overview of how different Next.js APIs affect caching: + +| API | Router Cache | Full Route Cache | Data Cache | React Cache | +| -------------------------------------------------------------------- | ------------ | --------------------- | --------------------- | ----------- | +| [``](#link) | Cache | | | | +| [`router.prefetch`](#routerprefetch) | Cache | | | | +| [`router.refresh`](#routerrefresh) | Revalidate | | | | +| [`fetch`](#fetch) | | | Cache | Cache | +| [`fetch.options.cache`](#fetch-optionscache) | | | Cache or Opt out | | +| [`fetch.options.next.revalidate`](#fetch-optionsnextrevalidate) | | Revalidate | Revalidate | | +| [`fetch.options.next.tags`](#fetch-optionsnexttag-and-revalidatetag) | | Cache | Cache | | +| [`revalidateTag`](#fetch-optionsnexttag-and-revalidatetag) | | Revalidate | Revalidate | | +| [`revalidatePath`](#revalidatepath) | | Revalidate | Revalidate | | +| [`const revalidate`](#segment-config-options) | | Revalidate or Opt out | Revalidate or Opt out | | +| [`const dynamic`](#segment-config-options) | | Cache or Opt out | Cache or Opt out | | +| [`cookies`](#cookies) | Revalidate | Opt out | | | +| [`headers`, `useSearchParams`, `searchParams`](#dynamic-functions) | | Opt out | | | +| [`generateStaticParams`](#generatestaticparams) | | Cache | | | +| [`React.cache`](#react-cache-function) | | | | Cache | +| [`unstable_cache`](#unstable_cache) (Coming Soon) | | | | | + +### `` + +By default, the `` component automatically prefetches routes from the Full Route Cache and adds the React Server Component Payload to the Router Cache. + +To disable prefetching, you can set the `prefetch` prop to `false`. But this will not skip the cache permanently, the route segment will still be cached client-side when the user visits the route. + +Learn more about the [`` component](/docs/app/api-reference/components/link). + +### `router.prefetch` + +The `prefetch` option of the `useRouter` hook can be used to manually prefetch a route. This adds the React Server Component Payload to the Router Cache. + +See the [`useRouter` hook](/docs/app/api-reference/functions/use-router) API reference. + +### `router.refresh` + +The `refresh` option of the `useRouter` hook can be used to manually refresh a route. This completely clears the Router Cache, and makes a new request to the server for the current route. `refresh` does not affect the Data or Full Route Cache. + +The rendered result will be reconciled on the client while preserving React state and browser state. + +See the [`useRouter` hook](/docs/app/api-reference/functions/use-router) API reference. + +### `fetch` + +Data returned from `fetch` is automatically cached in the Data Cache. + +```jsx +// Cached by default. `force-cache` is the default option and can be ommitted. +fetch(`https://...`, { cache: 'force-cache' }) +``` + +See the [`fetch` API Reference](/docs/app/api-reference/functions/fetch) for more options. + +### `fetch options.cache` + +You can opt out individual `fetch` requests of data caching by setting the `cache` option to `no-store`: + +```jsx +// Opt out of caching +fetch(`https://...`, { cache: 'no-store' }) +``` + +Since the render output depends on data, using `cache: 'no-store'` will also skip the Full Route Cache for the route where the `fetch` request is used. That is, the route will be dynamically rendered every request, but you can still have other cached data requests in the same route. + +See the [`fetch` API Reference](/docs/app/api-reference/functions/fetch) for more options. + +### `fetch options.next.revalidate` + +You can use the `next.revalidate` option of `fetch` to set the revalidation period (in seconds) of an individual `fetch` request. This will revalidate the Data Cache, which in turn will revalidate the Full Route Cache. Fresh data will be fetched, and components will be re-rendered on the server. + +```jsx +// Revalidate at most after 1 hour +fetch(`https://...`, { next: { revalidate: 3600 } }) +``` + +See the [`fetch` API reference](/docs/app/api-reference/functions/fetch) for more options. + +### `fetch options.next.tag` and `revalidateTag` + +Next.js has a cache tagging system for fine-grained data caching and revalidation. + +1. When using `fetch` or `unstable_cache`, you have the option to tag cache entries with one or more tags. +2. Then, you can call `revalidateTag` to purge the cache entries associated with that tag. + +For example, you can set a tag when fetching data: + +```jsx +// Cache data with a tag +fetch(`https://...`, { next: { tags: ['a', 'b', 'c'] } }) +``` + +Then, then call `revalidateTag` with a tag to purge the cache entry: + +```jsx +// Revalidate entries with a specific tag +revalidateTag('a') +``` + +There are two places you can use `revalidateTag`, depending on what you're trying to achieve: + +1. [Route Handlers](/docs/app/building-your-application/routing/route-handlers) - to revalidate data in response of a third party event (e.g. webhook). This will not invalidate the Router Cache immediately as the Router Handler isn't tied to a specific route. +2. [Server Actions](/docs/app/building-your-application/data-fetching/server-actions) - to revalidate data after a user action (e.g. form submission). This will invalidate the Router Cache for the associated route. + +### `revalidatePath` + +`revalidatePath` allows you manually revalidate data **and** re-render the route segments below a specific path in a single operation. Calling `revalidatePath` methods revalidate the Data Cache, which in turn invalidates the Full Route Cache. + +```jsx +revalidatePath('/') +``` + +There are two places you can use `revalidatePath`, depending on what you're trying to achieve: + +1. [Route Handlers](/docs/app/building-your-application/routing/route-handlers) - to revalidate data in response to a third party event (e.g. webhook). +2. [Server Actions](/docs/app/building-your-application/data-fetching/server-actions) - to revalidate data after a user interaction (e.g. form submission, clicking a button). + +See the [`revalidatePath` API reference](/docs/app/api-reference/functions/revalidatePath) for more information. + +> ** `revalidatePath` vs. `router.refresh`**: +> +> Calling `router.refresh` will clear the Router cache, and re-render route segments on the server without invalidating the Data Cache or the Full Route Cache. +> +> The difference is that `revalidatePath` purges the Data Cache and Full Route Cache, whereas `router.refresh()` does not change the Data Cache and Full Route Cache, as it is a client-side API. + +### Dynamic Functions + +`cookies`, `headers`, `useSearchParams`, and `searchParams` are all dynamic functions that depend on runtime incoming request information. Using them will opt a route out of the Full Route Cache, in other words, the route will be dynamically rendered. + +#### `cookies` + +Using `cookies.set` or `cookies.delete` in a Server Action invalidates the Router Cache to prevent routes that use cookies from becoming stale (e.g. to reflect authentication changes). + +See the [`cookies`](/docs/app/api-reference/functions/cookies) API reference. + +### Segment Config Options + +The Route Segment Config options can be used override the route segment defaults or when you're not able to use the `fetch` API (e.g. database client or 3rd party libraries). + +The following Route Segment Config options will opt out of the Data Cache and Full Route Cache: + +- `const dynamic = 'force-dynamic'` +- `const revalidate = 0` + +See the [Route Segment Config](/docs/app/api-reference/file-conventions/route-segment-config) documentation for more options. + +### `generateStaticParams` + +For [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes) (e.g. `app/blog/[slug]/page.js`), paths provided by `generateStaticParams` are cached in the Full Route Cache at build time. At request time, Next.js will also cache paths that weren't known at build time the first time they're visited. + +You can disable caching at request time by using `export const dynamicParams = false` option in a route segment. When this config option is used, only paths provided by `generateStaticParams` will be served, and other routes will 404 or match (in the case of [catch-all routes](/docs/app/building-your-application/routing/dynamic-routes#catch-all-segments)). + +See the [`generateStaticParams` API reference](/docs/app/api-reference/functions/generate-static-params). + +### React `cache` function + +The React `cache` function allows you to memoize the return value of a function, allowing you to call the same function multiple times while only executing it once. + +Since `fetch` requests are automatically memoized, you do not need to wrap it in React `cache`. However, you can use `cache` to manually memoize data requests for use cases when the `fetch` API is not suitable. For example, database clients, CMS clients, or GraphQL. + +```tsx filename="utils/get-item.ts" switcher +import { cache } from 'react' +import db from '@/lib/db' + +export const getItem = cache(async (id: string) => { + const item = await db.item.findUnique({ id }) + return item +}) +``` + +```jsx filename="utils/get-item.js" switcher +import { cache } from 'react' +import db from '@/lib/db' + +export const getItem = cache(async (id) => { + const item = await db.item.findUnique({ id }) + return item +}) +``` + +### `unstable_cache` + +`unstable_cache` is an experimental API for adding values to the Data Cache when the `fetch` API is not suitable. For example, when using database clients, CMS clients, or GraphQL. + +```jsx +import { unstable_cache } from 'next/cache' + +export default async function Page() { + const cachedData = await unstable_cache( + async () => { + const data = await db.query('...') + return data + }, + ['cache-key'], + { + tags: ['a', 'b', 'c'], + revalidate: 10, + } + )() +} +``` + +> **Warning**: This API is being developed, and we do not recommend using it in production. It's listed here to show the future direction of the Data Cache. diff --git a/docs/02-app/01-building-your-application/04-styling/01-css-modules.mdx b/docs/02-app/01-building-your-application/05-styling/01-css-modules.mdx similarity index 100% rename from docs/02-app/01-building-your-application/04-styling/01-css-modules.mdx rename to docs/02-app/01-building-your-application/05-styling/01-css-modules.mdx diff --git a/docs/02-app/01-building-your-application/04-styling/02-tailwind-css.mdx b/docs/02-app/01-building-your-application/05-styling/02-tailwind-css.mdx similarity index 100% rename from docs/02-app/01-building-your-application/04-styling/02-tailwind-css.mdx rename to docs/02-app/01-building-your-application/05-styling/02-tailwind-css.mdx diff --git a/docs/02-app/01-building-your-application/04-styling/03-css-in-js.mdx b/docs/02-app/01-building-your-application/05-styling/03-css-in-js.mdx similarity index 100% rename from docs/02-app/01-building-your-application/04-styling/03-css-in-js.mdx rename to docs/02-app/01-building-your-application/05-styling/03-css-in-js.mdx diff --git a/docs/02-app/01-building-your-application/04-styling/04-sass.mdx b/docs/02-app/01-building-your-application/05-styling/04-sass.mdx similarity index 100% rename from docs/02-app/01-building-your-application/04-styling/04-sass.mdx rename to docs/02-app/01-building-your-application/05-styling/04-sass.mdx diff --git a/docs/02-app/01-building-your-application/04-styling/index.mdx b/docs/02-app/01-building-your-application/05-styling/index.mdx similarity index 100% rename from docs/02-app/01-building-your-application/04-styling/index.mdx rename to docs/02-app/01-building-your-application/05-styling/index.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/01-images.mdx b/docs/02-app/01-building-your-application/06-optimizing/01-images.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/01-images.mdx rename to docs/02-app/01-building-your-application/06-optimizing/01-images.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/02-fonts.mdx b/docs/02-app/01-building-your-application/06-optimizing/02-fonts.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/02-fonts.mdx rename to docs/02-app/01-building-your-application/06-optimizing/02-fonts.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/03-scripts.mdx b/docs/02-app/01-building-your-application/06-optimizing/03-scripts.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/03-scripts.mdx rename to docs/02-app/01-building-your-application/06-optimizing/03-scripts.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/04-metadata.mdx b/docs/02-app/01-building-your-application/06-optimizing/04-metadata.mdx similarity index 95% rename from docs/02-app/01-building-your-application/05-optimizing/04-metadata.mdx rename to docs/02-app/01-building-your-application/06-optimizing/04-metadata.mdx index 3ef320bb809a1..eaf2b42596fc8 100644 --- a/docs/02-app/01-building-your-application/05-optimizing/04-metadata.mdx +++ b/docs/02-app/01-building-your-application/06-optimizing/04-metadata.mdx @@ -106,7 +106,7 @@ For all the available params, see the [API Reference](/docs/app/api-reference/fu > **Good to know**: > > - Both static and dynamic metadata through `generateMetadata` are **only supported in Server Components**. -> - When rendering a route, Next.js will [automatically deduplicate `fetch` requests](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/data-fetching/caching#react-cache) if `fetch` is unavailable. +> - `fetch` requests are automatically [memoized](/docs/app/building-your-application/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/caching#request-memoization) if `fetch` is unavailable. > - Next.js will wait for data fetching inside `generateMetadata` to complete before streaming UI to the client. This guarantees the first part of a [streamed response](/docs/app/building-your-application/routing/loading-ui-and-streaming) includes `` tags. ## File-based metadata @@ -281,7 +281,7 @@ export async function GET() { } ``` -`ImageResponse` integrates well with other Next.js APIs, including [Route Handlers](/docs/app/building-your-application/routing/router-handlers) and file-based Metadata. For example, you can use `ImageResponse` in a `opengraph-image.tsx` file to generate Open Graph images at build time or dynamically at request time. +`ImageResponse` integrates well with other Next.js APIs, including [Route Handlers](/docs/app/building-your-application/routing/route-handlers) and file-based Metadata. For example, you can use `ImageResponse` in a `opengraph-image.tsx` file to generate Open Graph images at build time or dynamically at request time. `ImageResponse` supports common CSS properties including flexbox and absolute positioning, custom fonts, text wrapping, centering, and nested images. [See the full list of supported CSS properties](/docs/app/api-reference/functions/image-response). diff --git a/docs/02-app/01-building-your-application/05-optimizing/05-static-assets.mdx b/docs/02-app/01-building-your-application/06-optimizing/05-static-assets.mdx similarity index 90% rename from docs/02-app/01-building-your-application/05-optimizing/05-static-assets.mdx rename to docs/02-app/01-building-your-application/06-optimizing/05-static-assets.mdx index 5809f1a589a94..41a3bf02ab265 100644 --- a/docs/02-app/01-building-your-application/05-optimizing/05-static-assets.mdx +++ b/docs/02-app/01-building-your-application/06-optimizing/05-static-assets.mdx @@ -32,4 +32,4 @@ For static metadata files, such as `robots.txt`, `favicon.ico`, etc, you should > Good to know: > > - The directory must be named `public`. The name cannot be changed and it's the only directory used to serve static assets. -> - Only assets that are in the `public` directory at [build time](/docs/app/api-reference/next-cli#build) will be served by Next.js. Files added at runtime won't be available. We recommend using a third-party service like [AWS S3](https://aws.amazon.com/s3/) for persistent file storage. +> - Only assets that are in the `public` directory at [build time](/docs/app/api-reference/next-cli#build) will be served by Next.js. Files added at request time won't be available. We recommend using a third-party service like [AWS S3](https://aws.amazon.com/s3/) for persistent file storage. diff --git a/docs/02-app/01-building-your-application/05-optimizing/06-lazy-loading.mdx b/docs/02-app/01-building-your-application/06-optimizing/06-lazy-loading.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/06-lazy-loading.mdx rename to docs/02-app/01-building-your-application/06-optimizing/06-lazy-loading.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx b/docs/02-app/01-building-your-application/06-optimizing/07-analytics.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/07-analytics.mdx rename to docs/02-app/01-building-your-application/06-optimizing/07-analytics.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/08-open-telemetry.mdx b/docs/02-app/01-building-your-application/06-optimizing/08-open-telemetry.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/08-open-telemetry.mdx rename to docs/02-app/01-building-your-application/06-optimizing/08-open-telemetry.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/09-instrumentation.mdx b/docs/02-app/01-building-your-application/06-optimizing/09-instrumentation.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/09-instrumentation.mdx rename to docs/02-app/01-building-your-application/06-optimizing/09-instrumentation.mdx diff --git a/docs/02-app/01-building-your-application/05-optimizing/index.mdx b/docs/02-app/01-building-your-application/06-optimizing/index.mdx similarity index 100% rename from docs/02-app/01-building-your-application/05-optimizing/index.mdx rename to docs/02-app/01-building-your-application/06-optimizing/index.mdx diff --git a/docs/02-app/01-building-your-application/06-configuring/01-typescript.mdx b/docs/02-app/01-building-your-application/07-configuring/01-typescript.mdx similarity index 97% rename from docs/02-app/01-building-your-application/06-configuring/01-typescript.mdx rename to docs/02-app/01-building-your-application/07-configuring/01-typescript.mdx index 34cae9f2529ce..04bb155acfca6 100644 --- a/docs/02-app/01-building-your-application/06-configuring/01-typescript.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/01-typescript.mdx @@ -131,9 +131,9 @@ function Card({ href }: { href: Route | URL }) { Next.js 13 has **enhanced type safety**. This includes: 1. **No serialization of data between fetching function and page**: You can `fetch` directly in components, layouts, and pages on the server. This data _does not_ need to be serialized (converted to a string) to be passed to the client side for consumption in React. Instead, since `app` uses Server Components by default, we can use values like `Date`, `Map`, `Set`, and more without any extra steps. Previously, you needed to manually type the boundary between server and client with Next.js-specific types. -2. **Streamlined data flow between components**: With the removal of `_app` in favor of root layouts, it is now easier to visualize the data flow between components and pages. Previously, data flowing between individual `pages` and `_app` were difficult to type and could introduce confusing bugs. With [colocated data fetching](/docs/app/building-your-application/data-fetching/fetching) in Next.js 13, this is no longer an issue. +2. **Streamlined data flow between components**: With the removal of `_app` in favor of root layouts, it is now easier to visualize the data flow between components and pages. Previously, data flowing between individual `pages` and `_app` were difficult to type and could introduce confusing bugs. With [colocated data fetching](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) in Next.js 13, this is no longer an issue. -[Data Fetching in Next.js](/docs/app/building-your-application/data-fetching/fetching) now provides as close to end-to-end type safety as possible without being prescriptive about your database or content provider selection. +[Data Fetching in Next.js](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) now provides as close to end-to-end type safety as possible without being prescriptive about your database or content provider selection. We're able to type the response data as you would expect with normal TypeScript. For example: diff --git a/docs/02-app/01-building-your-application/06-configuring/02-eslint.mdx b/docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx similarity index 100% rename from docs/02-app/01-building-your-application/06-configuring/02-eslint.mdx rename to docs/02-app/01-building-your-application/07-configuring/02-eslint.mdx diff --git a/docs/02-app/01-building-your-application/06-configuring/03-environment-variables.mdx b/docs/02-app/01-building-your-application/07-configuring/03-environment-variables.mdx similarity index 99% rename from docs/02-app/01-building-your-application/06-configuring/03-environment-variables.mdx rename to docs/02-app/01-building-your-application/07-configuring/03-environment-variables.mdx index 1620cbe826a73..813aa2946ed0c 100644 --- a/docs/02-app/01-building-your-application/06-configuring/03-environment-variables.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/03-environment-variables.mdx @@ -48,7 +48,7 @@ export async function getStaticProps() { -This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Route Handlers](/docs/app/building-your-application/routing/router-handlers). +This loads `process.env.DB_HOST`, `process.env.DB_USER`, and `process.env.DB_PASS` into the Node.js environment automatically allowing you to use them in [Route Handlers](/docs/app/building-your-application/routing/route-handlers). For example: diff --git a/docs/02-app/01-building-your-application/06-configuring/04-absolute-imports-and-module-aliases.mdx b/docs/02-app/01-building-your-application/07-configuring/04-absolute-imports-and-module-aliases.mdx similarity index 100% rename from docs/02-app/01-building-your-application/06-configuring/04-absolute-imports-and-module-aliases.mdx rename to docs/02-app/01-building-your-application/07-configuring/04-absolute-imports-and-module-aliases.mdx diff --git a/docs/02-app/01-building-your-application/06-configuring/05-mdx.mdx b/docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx similarity index 100% rename from docs/02-app/01-building-your-application/06-configuring/05-mdx.mdx rename to docs/02-app/01-building-your-application/07-configuring/05-mdx.mdx diff --git a/docs/02-app/01-building-your-application/06-configuring/06-src-directory.mdx b/docs/02-app/01-building-your-application/07-configuring/06-src-directory.mdx similarity index 100% rename from docs/02-app/01-building-your-application/06-configuring/06-src-directory.mdx rename to docs/02-app/01-building-your-application/07-configuring/06-src-directory.mdx diff --git a/docs/02-app/01-building-your-application/06-configuring/11-draft-mode.mdx b/docs/02-app/01-building-your-application/07-configuring/11-draft-mode.mdx similarity index 98% rename from docs/02-app/01-building-your-application/06-configuring/11-draft-mode.mdx rename to docs/02-app/01-building-your-application/07-configuring/11-draft-mode.mdx index f4014b7a3c149..e5fa9d81ebdfc 100644 --- a/docs/02-app/01-building-your-application/06-configuring/11-draft-mode.mdx +++ b/docs/02-app/01-building-your-application/07-configuring/11-draft-mode.mdx @@ -3,13 +3,13 @@ title: Draft Mode description: Next.js has draft mode to toggle between static and dynamic pages. You can learn how it works with App Router here. --- -Static rendering is useful when your pages fetch data from a headless CMS. However, it’s not ideal when you’re writing a draft on your headless CMS and want to view the draft immediately on your page. You’d want Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. You’d want Next.js to switch to [dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering) only for this specific case. +Static rendering is useful when your pages fetch data from a headless CMS. However, it’s not ideal when you’re writing a draft on your headless CMS and want to view the draft immediately on your page. You’d want Next.js to render these pages at **request time** instead of build time and fetch the draft content instead of the published content. You’d want Next.js to switch to [dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering only for this specific case. Next.js has a feature called **Draft Mode** which solves this problem. Here are instructions on how to use it. ## Step 1: Create and access the Route Handler -First, create a [Route Handler](/docs/app/building-your-application/routing/router-handlers). It can have any name - e.g. `app/api/draft/route.ts` +First, create a [Route Handler](/docs/app/building-your-application/routing/route-handlers). It can have any name - e.g. `app/api/draft/route.ts` Then, import `draftMode` from `next/headers` and call the `enable()` method. diff --git a/docs/02-app/01-building-your-application/06-configuring/index.mdx b/docs/02-app/01-building-your-application/07-configuring/index.mdx similarity index 100% rename from docs/02-app/01-building-your-application/06-configuring/index.mdx rename to docs/02-app/01-building-your-application/07-configuring/index.mdx diff --git a/docs/02-app/01-building-your-application/07-deploying/01-static-exports.mdx b/docs/02-app/01-building-your-application/08-deploying/01-static-exports.mdx similarity index 98% rename from docs/02-app/01-building-your-application/07-deploying/01-static-exports.mdx rename to docs/02-app/01-building-your-application/08-deploying/01-static-exports.mdx index 0e7cb68429369..578a2f7352f84 100644 --- a/docs/02-app/01-building-your-application/07-deploying/01-static-exports.mdx +++ b/docs/02-app/01-building-your-application/08-deploying/01-static-exports.mdx @@ -68,7 +68,7 @@ export default async function Page() { ### Client Components -If you want to perform data fetching on the client, you can use a Client Component with [SWR](https://github.com/vercel/swr) to deduplicate requests. +If you want to perform data fetching on the client, you can use a Client Component with [SWR](https://github.com/vercel/swr) to memoize requests. ```tsx filename="app/other/page.tsx" switcher 'use client' @@ -232,7 +232,7 @@ export default function Page() { ### Route Handlers -Route Handlers will render a static response when running `next build`. Only the `GET` HTTP verb is supported. This can be used to generate static HTML, JSON, TXT, or other files from dynamic or static data. For example: +Route Handlers will render a static response when running `next build`. Only the `GET` HTTP verb is supported. This can be used to generate static HTML, JSON, TXT, or other files from cached or uncached data. For example: ```ts filename="app/data.json/route.ts" switcher import { NextResponse } from 'next/server' @@ -293,7 +293,7 @@ The following additional dynamic features are not supported with a static export - `redirects` in `next.config.js` - `headers` in `next.config.js` - Middleware -- [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/revalidating) +- [Incremental Static Regeneration](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) diff --git a/docs/02-app/01-building-your-application/07-deploying/index.mdx b/docs/02-app/01-building-your-application/08-deploying/index.mdx similarity index 100% rename from docs/02-app/01-building-your-application/07-deploying/index.mdx rename to docs/02-app/01-building-your-application/08-deploying/index.mdx diff --git a/docs/02-app/01-building-your-application/08-upgrading/01-codemods.mdx b/docs/02-app/01-building-your-application/09-upgrading/01-codemods.mdx similarity index 100% rename from docs/02-app/01-building-your-application/08-upgrading/01-codemods.mdx rename to docs/02-app/01-building-your-application/09-upgrading/01-codemods.mdx diff --git a/docs/02-app/01-building-your-application/08-upgrading/02-app-router-migration.mdx b/docs/02-app/01-building-your-application/09-upgrading/02-app-router-migration.mdx similarity index 97% rename from docs/02-app/01-building-your-application/08-upgrading/02-app-router-migration.mdx rename to docs/02-app/01-building-your-application/09-upgrading/02-app-router-migration.mdx index ed5b37cbfee51..483cc3de8d1c0 100644 --- a/docs/02-app/01-building-your-application/08-upgrading/02-app-router-migration.mdx +++ b/docs/02-app/01-building-your-application/09-upgrading/02-app-router-migration.mdx @@ -384,7 +384,7 @@ export default function HomePage({ recentPosts }) { - Create a new `app/page.tsx` file inside the `app` directory. This is a Server Component by default. - Import the `home-page.tsx` Client Component into the page. -- If you were fetching data in `pages/index.js`, move the data fetching logic directly into the Server Component using the new [data fetching APIs](/docs/app/building-your-application/data-fetching/fetching). See the [data fetching upgrade guide](#step-6-migrating-data-fetching-methods) for more details. +- If you were fetching data in `pages/index.js`, move the data fetching logic directly into the Server Component using the new [data fetching APIs](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating). See the [data fetching upgrade guide](#step-6-migrating-data-fetching-methods) for more details. ```tsx filename="app/page.tsx" switcher // Import your Client Component @@ -472,7 +472,7 @@ In addition, the new `useRouter` hook has the following changes: - The `locale`, `locales`, `defaultLocales`, `domainLocales` values have been removed because built-in i18n Next.js features are no longer necessary in the `app` directory. [Learn more about i18n](/docs/pages/building-your-application/routing/internationalization). - `basePath` has been removed. The alternative will not be part of `useRouter`. It has not yet been implemented. - `asPath` has been removed because the concept of `as` has been removed from the new router. -- `isReady` has been removed because it is no longer necessary. During [static rendering](/docs/app/building-your-application/rendering#static-rendering), any component that uses the [`useSearchParams()`](/docs/app/api-reference/functions/use-params) hook will skip the prerendering step and instead be rendered on the client at runtime. +- `isReady` has been removed because it is no longer necessary. During [static rendering](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default), any component that uses the [`useSearchParams()`](/docs/app/api-reference/functions/use-params) hook will skip the prerendering step and instead be rendered on the client at runtime. [View the `useRouter()` API reference](/docs/app/api-reference/functions/use-router). @@ -549,7 +549,7 @@ export default function Dashboard({ projects }) { In the `app` directory, we can colocate our data fetching inside our React components using [Server Components](/docs/getting-started/react-essentials#server-components). This allows us to send less JavaScript to the client, while maintaining the rendered HTML from the server. -By setting the `cache` option to `no-store`, we can indicate that the fetched data should [never be cached](/docs/app/building-your-application/data-fetching/caching). This is similar to `getServerSideProps` in the `pages` directory. +By setting the `cache` option to `no-store`, we can indicate that the fetched data should [never be cached](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating. This is similar to `getServerSideProps` in the `pages` directory. ```tsx filename="app/dashboard/page.tsx" switcher // `app` directory @@ -808,11 +808,11 @@ export default async function Post({ params }) { } ``` -With [`dynamicParams`](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) set to `true` (the default), when a route segment is requested that hasn't been generated, it will be server-rendered and cached as [static data](/docs/app/building-your-application/data-fetching#static-and-dynamic-data-fetching) on success. +With [`dynamicParams`](/docs/app/api-reference/file-conventions/route-segment-config#dynamicparams) set to `true` (the default), when a route segment is requested that hasn't been generated, it will be server-rendered and cached. #### Incremental Static Regeneration (`getStaticProps` with `revalidate`) -In the `pages` directory, the `getStaticProps` function allows you to add a `revalidate` field to automatically regenerate a page after a certain amount of time. This is called [Incremental Static Regeneration (ISR)](/docs/app/building-your-application/data-fetching/fetching#static-data-fetching) and helps you update static content without redeploying. +In the `pages` directory, the `getStaticProps` function allows you to add a `revalidate` field to automatically regenerate a page after a certain amount of time. ```jsx filename="pages/index.js" // `pages` directory @@ -857,7 +857,7 @@ export default async function PostList() { #### API Routes -API Routes continue to work in the `pages/api` directory without any changes. However, they have been replaced by [Route Handlers](/docs/app/building-your-application/routing/router-handlers) in the `app` directory. +API Routes continue to work in the `pages/api` directory without any changes. However, they have been replaced by [Route Handlers](/docs/app/building-your-application/routing/route-handlers) in the `app` directory. Route Handlers allow you to create custom request handlers for a given route using the Web [Request](https://developer.mozilla.org/en-US/docs/Web/API/Request) and [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response) APIs. @@ -869,7 +869,7 @@ export async function GET(request: Request) {} export async function GET(request) {} ``` -> **Good to know**: If you previously used API routes to call an external API from the client, you can now use [Server Components](/docs/getting-started/react-essentials#server-components) instead to securely fetch data. Learn more about [data fetching](/docs/app/building-your-application/data-fetching/fetching). +> **Good to know**: If you previously used API routes to call an external API from the client, you can now use [Server Components](/docs/getting-started/react-essentials#server-components) instead to securely fetch data. Learn more about [data fetching](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating). ### Step 7: Styling diff --git a/docs/02-app/01-building-your-application/08-upgrading/index.mdx b/docs/02-app/01-building-your-application/09-upgrading/index.mdx similarity index 100% rename from docs/02-app/01-building-your-application/08-upgrading/index.mdx rename to docs/02-app/01-building-your-application/09-upgrading/index.mdx diff --git a/docs/02-app/02-api-reference/01-components/link.mdx b/docs/02-app/02-api-reference/01-components/link.mdx index eb4d10e1cfa44..2541075c03be2 100644 --- a/docs/02-app/02-api-reference/01-components/link.mdx +++ b/docs/02-app/02-api-reference/01-components/link.mdx @@ -13,7 +13,7 @@ description: Enable fast client-side navigation with the built-in `next/link` co -`` is a React component that extends the HTML `` element to provide [prefetching](/docs/app/building-your-application/routing/linking-and-navigating#prefetching) and client-side navigation between routes. It is the primary way to navigate between routes in Next.js. +`` is a React component that extends the HTML `` element to provide [prefetching](/docs/app/building-your-application/routing/linking-and-navigating#1-prefetching) and client-side navigation between routes. It is the primary way to navigate between routes in Next.js. diff --git a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx index 009a47b8ef1b6..2d6db2dc2c3b6 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/app-icons.mdx @@ -172,7 +172,7 @@ export default function Icon() { > **Good to know** > -> - By default, generated icons are [**statically optimized**](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default) (generated at build time and cached) unless they use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) or [dynamic data fetching](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-data-fetching). +> - By default, generated icons are [**statically optimized**](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default) (generated at build time and cached) unless they use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) or uncached data. > - You can generate multiple icons in the same file using [`generateImageMetadata`](/docs/app/api-reference/functions/generate-image-metadata). > - You cannot generate a `favicon` icon. Use [`icon`](#icon) or a [favicon.ico](#favicon) file instead. @@ -256,7 +256,7 @@ export default function Icon() {} #### Route Segment Config -`icon` and `apple-icon` are specialized [Route Handlers](/docs/app/building-your-application/routing/router-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts. +`icon` and `apple-icon` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts. | Option | Type | Default | | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------- | diff --git a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/opengraph-image.mdx b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/opengraph-image.mdx index ce5dfebb99b30..76fa036fb109a 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/01-metadata/opengraph-image.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/01-metadata/opengraph-image.mdx @@ -84,7 +84,7 @@ Generate a route segment's shared image by creating an `opengraph-image` or `twi > **Good to know** > -> - By default, generated images are [**statically optimized**](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default) (generated at build time and cached) unless they use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) or [dynamic data fetching](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-data-fetching). +> - By default, generated images are [**statically optimized**](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default) (generated at build time and cached) unless they use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) or uncached data. > - You can generate multiple Images in the same file using [`generateImageMetadata`](/docs/app/api-reference/functions/generate-image-metadata). The easiest way to generate an image is to use the [ImageResponse](/docs/app/api-reference/functions/image-response) API from `next/server`. @@ -311,7 +311,7 @@ export default function Image() {} #### Route Segment Config -`opengraph-image` and `twitter-image` are specialized [Route Handlers](/docs/app/building-your-application/routing/router-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts. +`opengraph-image` and `twitter-image` are specialized [Route Handlers](/docs/app/building-your-application/routing/route-handlers) that can use the same [route segment configuration](/docs/app/api-reference/file-conventions/route-segment-config) options as Pages and Layouts. | Option | Type | Default | | -------------------------------------------------------------------------------------------------- | -------------------------------------------------------- | ---------- | @@ -339,7 +339,7 @@ export default function Image() {} This example uses the `params` object and external data to generate the image. > **Good to know**: -> By default, this generated image will be [statically optimized](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default). You can configure the individual `fetch` [`options`](/docs/app/api-reference/functions/fetch) or route segments [options](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) to change this behavior. +> By default, this generated image will be [statically optimized](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default). You can configure the individual `fetch` [`options`](/docs/app/api-reference/functions/fetch) or route segments [options](/docs/app/api-reference/file-conventions/route-segment-config#revalidate) to change this behavior. ```tsx filename="app/posts/[slug]/opengraph-image.tsx" switcher import { ImageResponse } from 'next/server' diff --git a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx index 2a852b5ff75c7..737d4baf1aac8 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/layout.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/layout.mdx @@ -92,9 +92,9 @@ export default function ShopLayout({ children, params }) { ## Good to know -### Layout's do not receive `searchParams` +### Layouts do not receive `searchParams` -Unlike [Pages](/docs/app/api-reference/file-conventions/page), Layout components **do not** receive the `searchParams` prop. This is because a shared layout is [not re-rendered during navigation](/docs/app/building-your-application/routing#partial-rendering) which could lead to stale `searchParams` between navigations. +Unlike [Pages](/docs/app/api-reference/file-conventions/page), Layout components **do not** receive the `searchParams` prop. This is because a shared layout is [not re-rendered during navigation](/docs/app/building-your-application/routing/linking-and-navigating#3-partial-rendering) which could lead to stale `searchParams` between navigations. When using client-side navigation, Next.js automatically only renders the part of the page below the common layout between two routes. diff --git a/docs/02-app/02-api-reference/02-file-conventions/page.mdx b/docs/02-app/02-api-reference/02-file-conventions/page.mdx index 29d306855b82a..21af2f76323ff 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/page.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/page.mdx @@ -47,7 +47,7 @@ An object containing the [search parameters](https://developer.mozilla.org/en-US > **Good to know**: > -> - `searchParams` is a **[Dynamic API](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions)** whose values cannot be known ahead of time. Using it will opt the page into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering)** at request time. +> - `searchParams` is a **[Dynamic API](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions)** whose values cannot be known ahead of time. Using it will opt the page into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering)** at request time. > - `searchParams` returns a plain JavaScript object and not a `URLSearchParams` instance. ## Version History diff --git a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx index bda5d2b418250..998af5976e976 100644 --- a/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx +++ b/docs/02-app/02-api-reference/02-file-conventions/route-segment-config.mdx @@ -3,7 +3,7 @@ title: Route Segment Config description: Learn about how to configure options for Next.js route segments. --- -The Route Segment options allows you configure the behavior of a [Page](/docs/app/building-your-application/routing/pages-and-layouts), [Layout](/docs/app/building-your-application/routing/pages-and-layouts), or [Route Handler](/docs/app/building-your-application/routing/router-handlers) by directly exporting the following variables: +The Route Segment options allows you configure the behavior of a [Page](/docs/app/building-your-application/routing/pages-and-layouts), [Layout](/docs/app/building-your-application/routing/pages-and-layouts), or [Route Handler](/docs/app/building-your-application/routing/route-handlers) by directly exporting the following variables: | Option | Type | Default | | ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- | -------------------------- | @@ -62,18 +62,18 @@ export const dynamic = 'auto' > **Good to know**: The new model in the `app` directory favors granular caching control at the `fetch` request level over the binary all-or-nothing model of `getServerSideProps` and `getStaticProps` at the page-level in the `pages` directory. The `dynamic` option is a way to opt back in to the previous model as a convenience and provides a simpler migration path. - **`'auto'`** (default): The default option to cache as much as possible without preventing any components from opting into dynamic behavior. -- **`'force-dynamic'`**: Force dynamic rendering and dynamic data fetching of a layout or page by disabling all caching of `fetch` requests and always revalidating. This option is equivalent to: +- **`'force-dynamic'`**: Force dynamic rendering and uncached data fetching of a layout or page by disabling all caching of `fetch` requests and always revalidating. This option is equivalent to: - `getServerSideProps()` in the `pages` directory. - Setting the option of every `fetch()` request in a layout or page to `{ cache: 'no-store', next: { revalidate: 0 } }`. - Setting the segment config to `export const fetchCache = 'force-no-store'` -- **`'error'`**: Force static rendering and static data fetching of a layout or page by causing an error if any components use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) or [dynamic fetches](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-data-fetching). This option is equivalent to: +- **`'error'`**: Force static rendering and cache the data of a layout or page by causing an error if any components use [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) or uncached data. This option is equivalent to: - `getStaticProps()` in the `pages` directory. - Setting the option of every `fetch()` request in a layout or page to `{ cache: 'force-cache' }`. - Setting the segment config to `fetchCache = 'only-cache', dynamicParams = false`. - `dynamic = 'error'` changes the default of `dynamicParams` from `true` to `false`. You can opt back into dynamically rendering pages for dynamic params not generated by `generateStaticParams` by manually setting `dynamicParams = true`. -- **`'force-static'`**: Force static rendering and static data fetching of a layout or page by forcing [`cookies()`](/docs/app/api-reference/functions/cookies), [`headers()`](/docs/app/api-reference/functions/headers) and [`useSearchParams()`](/docs/app/api-reference/functions/use-search-params) to return empty values. +- **`'force-static'`**: Force static rendering and cache the data of a layout or page by forcing [`cookies()`](/docs/app/api-reference/functions/cookies), [`headers()`](/docs/app/api-reference/functions/headers) and [`useSearchParams()`](/docs/app/api-reference/functions/use-search-params) to return empty values. > **Good to know**: > @@ -114,8 +114,8 @@ export const revalidate = false // false | 'force-cache' | 0 | number ``` -- **`false`**: (default) The default heuristic to cache any `fetch` requests that set their `cache` option to `'force-cache'` or are discovered before a [dynamic function](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) is used. Semantically equivalent to `revalidate: Infinity` which effectively means the resource should be cached indefinitely. It is still possible for individual `fetch` requests to use `cache: 'no-store'` or `revalidate: 0` to avoid being cached and make the route dynamically rendered. Or set `revalidate` to a positive number lower than the route default to increase the revalidation frequency of a route. -- **`0`**: Ensure a layout or page is always [dynamically rendered](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering) even if no dynamic functions or dynamic data fetches are discovered. This option changes the default of `fetch` requests that do not set a `cache` option to `'no-store'` but leaves `fetch` requests that opt into `'force-cache'` or use a positive `revalidate` as is. +- **`false`**: (default) The default heuristic to cache any `fetch` requests that set their `cache` option to `'force-cache'` or are discovered before a [dynamic function](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) is used. Semantically equivalent to `revalidate: Infinity` which effectively means the resource should be cached indefinitely. It is still possible for individual `fetch` requests to use `cache: 'no-store'` or `revalidate: 0` to avoid being cached and make the route dynamically rendered. Or set `revalidate` to a positive number lower than the route default to increase the revalidation frequency of a route. +- **`0`**: Ensure a layout or page is always [dynamically rendered](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering) even if no dynamic functions or uncached data fetches are discovered. This option changes the default of `fetch` requests that do not set a `cache` option to `'no-store'` but leaves `fetch` requests that opt into `'force-cache'` or use a positive `revalidate` as is. - **`number`**: (in seconds) Set the default revalidation frequency of a layout or page to `n` seconds. #### Revalidation Frequency @@ -128,7 +128,7 @@ export const revalidate = false
This is an advanced option that should only be used if you specifically need to override the default behavior. -By default, Next.js **will cache** any `fetch()` requests that are reachable **before** any [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) are used and **will not cache** `fetch` requests that are discovered **after** dynamic functions are used. +By default, Next.js **will cache** any `fetch()` requests that are reachable **before** any [dynamic functions](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) are used and **will not cache** `fetch` requests that are discovered **after** dynamic functions are used. `fetchCache` allows you to override the default `cache` option of all `fetch` requests in a layout or page. diff --git a/docs/02-app/02-api-reference/04-functions/cookies.mdx b/docs/02-app/02-api-reference/04-functions/cookies.mdx index 16852fc8305c9..c9d88f79d985d 100644 --- a/docs/02-app/02-api-reference/04-functions/cookies.mdx +++ b/docs/02-app/02-api-reference/04-functions/cookies.mdx @@ -8,9 +8,9 @@ related: - app/building-your-application/data-fetching/server-actions --- -The `cookies` function allows you to read the HTTP incoming request cookies from a [Server Component](/docs/getting-started/react-essentials) or write outgoing request cookies in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/router-handlers). +The `cookies` function allows you to read the HTTP incoming request cookies from a [Server Component](/docs/getting-started/react-essentials) or write outgoing request cookies in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/route-handlers). -> **Good to know**: `cookies()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering)** at request time. +> **Good to know**: `cookies()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering)** at request time. ## `cookies().get(name)` @@ -62,7 +62,7 @@ export default function Page() { A method that takes a cookie name, value, and options and sets the outgoing request cookie. -> **Good to know**: `.set()` is only available in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/router-handlers). +> **Good to know**: `.set()` is only available in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/route-handlers). ```js filename="app/actions.js" 'use server' @@ -87,7 +87,7 @@ async function create(data) { To "delete" a cookie, you must set a new cookie with the same name and an empty value. You can also set the `maxAge` to `0` to expire the cookie immediately. -> **Good to know**: `.set()` is only available in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/router-handlers). +> **Good to know**: `.set()` is only available in a [Server Action](/docs/app/building-your-application/data-fetching/server-actions) or [Route Handler](/docs/app/building-your-application/routing/route-handlers). ```js filename="app/actions.js" 'use server' diff --git a/docs/02-app/02-api-reference/04-functions/fetch.mdx b/docs/02-app/02-api-reference/04-functions/fetch.mdx index c70f7d55a8dbd..dd74d14d960e3 100644 --- a/docs/02-app/02-api-reference/04-functions/fetch.mdx +++ b/docs/02-app/02-api-reference/04-functions/fetch.mdx @@ -59,20 +59,20 @@ Further, Next.js polyfills `fetch` on both the client and the server, so you can ### `options.cache` -Configure how the request should interact with Next.js HTTP cache. +Configure how the request should interact with Next.js [Data Cache](/docs/app/building-your-application/caching#data-cache). ```ts fetch(`https://...`, { cache: 'force-cache' | 'no-store' }) ``` -- **`force-cache`** (default) - Next.js looks for a matching request in its HTTP cache. +- **`force-cache`** (default) - Next.js looks for a matching request in its Data Cache. - If there is a match and it is fresh, it will be returned from the cache. - If there is no match or a stale match, Next.js will fetch the resource from the remote server and update the cache with the downloaded resource. - **`no-store`** - Next.js fetches the resource from the remote server on every request without looking in the cache, and it will not update the cache with the downloaded resource. > **Good to know**: > -> - If you don't provide a `cache` option, Next.js will default to `force-cache`, unless a [dynamic function](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions) such as `cookies()` is used, in which case it will default to `no-store`. +> - If you don't provide a `cache` option, Next.js will default to `force-cache`, unless a [dynamic function](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) such as `cookies()` is used, in which case it will default to `no-store`. > - The `no-cache` option behaves the same way as `no-store` in Next.js. ### `options.next.revalidate` @@ -83,7 +83,7 @@ fetch(`https://...`, { next: { revalidate: false | 0 | number } }) Set the cache lifetime of a resource (in seconds). -- **`false`** - Cache the resource indefinitely. Semantically equivalent to `revalidate: Infinity`. The [HTTP cache](/docs/app/building-your-application/data-fetching#caching-data) may evict older resources over time. +- **`false`** - Cache the resource indefinitely. Semantically equivalent to `revalidate: Infinity`. The HTTP cache may evict older resources over time. - **`0`** - Prevent the resource from being cached. - **`number`** - (in seconds) Specify the resource should have a cache lifetime of at most `n` seconds. diff --git a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx index 7269dee90e6be..487e2a0fea1c7 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-metadata.mdx @@ -162,7 +162,7 @@ export default function Page({ params, searchParams }) {} > **Good to know**: > > - If metadata doesn't depend on runtime information, it should be defined using the static [`metadata` object](#the-metadata-object) rather than `generateMetadata`. -> - When rendering a route, Next.js will [automatically deduplicate `fetch` requests](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/data-fetching/caching#react-cache) if `fetch` is unavailable. +> - `fetch` requests are automatically [memoized](/docs/app/building-your-application/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/caching#request-memoization) if `fetch` is unavailable. > - `searchParams` are only available in `page.js` segments. > - The [`redirect()`](/docs/app/api-reference/functions/redirect) and [`notFound()`](/docs/app/api-reference/functions/not-found) Next.js methods can also be used inside `generateMetadata`. diff --git a/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx b/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx index b36087ba2aad3..3f1431279fccc 100644 --- a/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx +++ b/docs/02-app/02-api-reference/04-functions/generate-static-params.mdx @@ -3,7 +3,7 @@ title: generateStaticParams description: API reference for the generateStaticParams function. --- -The `generateStaticParams` function can be used in combination with [dynamic route segments](/docs/app/building-your-application/routing/dynamic-routes) to [**statically generate**](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default) routes at build time instead of on-demand at request time. +The `generateStaticParams` function can be used in combination with [dynamic route segments](/docs/app/building-your-application/routing/dynamic-routes) to [**statically generate**](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default) routes at build time instead of on-demand at request time. ```jsx filename="app/blog/[slug]/page.js" // Return a list of `params` to populate the [slug] dynamic segment @@ -299,7 +299,7 @@ export default function Page({ params }) { } ``` -> **Good to know**: When rendering a route, Next.js will [automatically deduplicate `fetch` requests](/docs/app/building-your-application/data-fetching#automatic-fetch-request-deduping) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/data-fetching/caching#react-cache) if `fetch` is unavailable. +> **Good to know**: `fetch` requests are automatically [memoized](/docs/app/building-your-application/caching#request-memoization) for the same data across `generateMetadata`, `generateStaticParams`, Layouts, Pages, and Server Components. React [`cache` can be used](/docs/app/building-your-application/caching#request-memoization) if `fetch` is unavailable. ## Version History diff --git a/docs/02-app/02-api-reference/04-functions/headers.mdx b/docs/02-app/02-api-reference/04-functions/headers.mdx index 334f8570f646a..788a6a37eb5de 100644 --- a/docs/02-app/02-api-reference/04-functions/headers.mdx +++ b/docs/02-app/02-api-reference/04-functions/headers.mdx @@ -33,7 +33,7 @@ export default function Page() { > **Good to know**: > -> - `headers()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering)** at request time. +> - `headers()` is a **[Dynamic Function](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions)** whose returned values cannot be known ahead of time. Using it in a layout or page will opt a route into **[dynamic rendering](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering)** at request time. ### API Reference @@ -60,7 +60,7 @@ const headersList = headers() #### Usage with Data Fetching -`headers()` can be used in combination with [Suspense for Data Fetching](/docs/app/building-your-application/data-fetching/fetching). +`headers()` can be used in combination with [Suspense for Data Fetching](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating). ```jsx filename="app/page.js" import { headers } from 'next/headers' diff --git a/docs/02-app/02-api-reference/04-functions/redirect.mdx b/docs/02-app/02-api-reference/04-functions/redirect.mdx index 764dea607d581..7daa12db5d2b4 100644 --- a/docs/02-app/02-api-reference/04-functions/redirect.mdx +++ b/docs/02-app/02-api-reference/04-functions/redirect.mdx @@ -3,7 +3,7 @@ title: redirect description: API Reference for the redirect function. --- -The `redirect` function allows you to redirect the user to another URL. `redirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/building-your-application/routing/router-handlers), and [Server Actions](/docs/app/building-your-application/data-fetching/server-actions). +The `redirect` function allows you to redirect the user to another URL. `redirect` can be used in Server Components, Client Components, [Route Handlers](/docs/app/building-your-application/routing/route-handlers), and [Server Actions](/docs/app/building-your-application/data-fetching/server-actions). If you need to redirect to a 404, use the [`notFound` function](/docs/app/api-reference/functions/not-found) instead. diff --git a/docs/02-app/02-api-reference/04-functions/revalidatePath.mdx b/docs/02-app/02-api-reference/04-functions/revalidatePath.mdx index ee406c03715ba..2d002288ecc36 100644 --- a/docs/02-app/02-api-reference/04-functions/revalidatePath.mdx +++ b/docs/02-app/02-api-reference/04-functions/revalidatePath.mdx @@ -10,7 +10,7 @@ import { NextRequest, NextResponse } from 'next/server' import { revalidatePath } from 'next/cache' export async function GET(request: NextRequest) { - const path = request.nextUrl.searchParams.get('path') || '/' + const path = request.nextUrl.searchParams.get('path') revalidatePath(path) return NextResponse.json({ revalidated: true, now: Date.now() }) } @@ -21,7 +21,7 @@ import { NextResponse } from 'next/server' import { revalidatePath } from 'next/cache' export async function GET(request) { - const path = request.nextUrl.searchParams.get('path') || '/' + const path = request.nextUrl.searchParams.get('path') revalidatePath(path) return NextResponse.json({ revalidated: true, now: Date.now() }) } diff --git a/docs/02-app/02-api-reference/04-functions/use-router.mdx b/docs/02-app/02-api-reference/04-functions/use-router.mdx index 220304457c93b..48fff5a9b9961 100644 --- a/docs/02-app/02-api-reference/04-functions/use-router.mdx +++ b/docs/02-app/02-api-reference/04-functions/use-router.mdx @@ -44,14 +44,13 @@ export default function Page() { - `router.push(href: string)`: Perform a client-side navigation to the provided route. Adds a new entry into the [browser’s history](https://developer.mozilla.org/en-US/docs/Web/API/History_API) stack. - `router.replace(href: string)`: Perform a client-side navigation to the provided route without adding a new entry into the [browser’s history stack](https://developer.mozilla.org/en-US/docs/Web/API/History_API). - `router.refresh()`: Refresh the current route. Making a new request to the server, re-fetching data requests, and re-rendering Server Components. The client will merge the updated React Server Component payload without losing unaffected client-side React (e.g. `useState`) or browser state (e.g. scroll position). -- `router.prefetch(href: string)`: [Prefetch](/docs/app/building-your-application/routing/linking-and-navigating#prefetching) the provided route for faster client-side transitions. -- `router.back()`: Navigate back to the previous route in the browser’s history stack using [soft navigation](/docs/app/building-your-application/routing/linking-and-navigating#soft-navigation). -- `router.forward()`: Navigate forwards to the next page in the browser’s history stack using [soft navigation](/docs/app/building-your-application/routing/linking-and-navigating#soft-navigation). +- `router.prefetch(href: string)`: [Prefetch](/docs/app/building-your-application/routing/linking-and-navigating#1-prefetching) the provided route for faster client-side transitions. +- `router.back()`: Navigate back to the previous route in the browser’s history stack. +- `router.forward()`: Navigate forwards to the next page in the browser’s history stack. > **Good to know**: > -> - The `push()` and `replace()` methods will perform a [soft navigation](/docs/app/building-your-application/routing/linking-and-navigating#soft-navigation) if the new route has been prefetched, and either, doesn't include [dynamic segments](/docs/app/building-your-application/routing/dynamic-routes) or has the same dynamic parameters as the current route. -> - `next/link` automatically prefetch routes as they become visible in the viewport. +> - The `` component automatically prefetch routes as they become visible in the viewport. > - `refresh()` could re-produce the same result if fetch requests are cached. Other dynamic functions like `cookies` and `headers` could also change the response. > **Migrating from the `pages` directory:** @@ -111,7 +110,7 @@ export default function Layout({ children }) { } ``` -> **Good to know**: `` is wrapped in a [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) because[`useSearchParams()`](/docs/app/api-reference/functions/use-search-params) causes client-side rendering up to the closest `Suspense` boundary during [static rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default). [Learn more](/docs/app/api-reference/functions/use-search-params#behavior). +> **Good to know**: `` is wrapped in a [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) because[`useSearchParams()`](/docs/app/api-reference/functions/use-search-params) causes client-side rendering up to the closest `Suspense` boundary during [static rendering](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default). [Learn more](/docs/app/api-reference/functions/use-search-params#behavior). | Version | Changes | | --------- | ---------------------------------------------- | diff --git a/docs/02-app/02-api-reference/04-functions/use-search-params.mdx b/docs/02-app/02-api-reference/04-functions/use-search-params.mdx index 405a918d093e1..7b1552eadb035 100644 --- a/docs/02-app/02-api-reference/04-functions/use-search-params.mdx +++ b/docs/02-app/02-api-reference/04-functions/use-search-params.mdx @@ -71,14 +71,14 @@ const searchParams = useSearchParams() > **Good to know**: > -> - `useSearchParams` is a [Client Component](/docs/getting-started/react-essentials) hook and is **not supported** in [Server Components](/docs/getting-started/react-essentials) to prevent stale values during [partial rendering](/docs/app/building-your-application/routing#partial-rendering). +> - `useSearchParams` is a [Client Component](/docs/getting-started/react-essentials) hook and is **not supported** in [Server Components](/docs/getting-started/react-essentials) to prevent stale values during [partial rendering](/docs/app/building-your-application/routing/linking-and-navigating#3-partial-rendering). > - If an application includes the `/pages` directory, `useSearchParams` will return `ReadonlyURLSearchParams | null`. The `null` value is for compatibility during migration since search params cannot be known during pre-rendering of a page that doesn't use `getServerSideProps` ## Behavior ### Static Rendering -If a route is [statically rendered](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#static-rendering-default), calling `useSearchParams()` will cause the tree up to the closest [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) to be client-side rendered. +If a route is [statically rendered](/docs/app/building-your-application/rendering/static-and-dynamic#static-rendering-default), calling `useSearchParams()` will cause the tree up to the closest [`Suspense` boundary](/docs/app/building-your-application/routing/loading-ui-and-streaming#example) to be client-side rendered. This allows a part of the page to be statically rendered while the dynamic part that uses `searchParams` is client-side rendered. @@ -172,7 +172,7 @@ export default function Page() { ### Dynamic Rendering -If a route is [dynamically rendered](/docs/app/building-your-application/rendering/static-and-dynamic-rendering#dynamic-rendering), `useSearchParams` will be available on the server during the initial server render of the Client Component. +If a route is [dynamically rendered](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-rendering), `useSearchParams` will be available on the server during the initial server render of the Client Component. > **Good to know**: Setting the [`dynamic` route segment config option](/docs/app/api-reference/file-conventions/route-segment-config#dynamic) to `force-dynamic` can be used to force dynamic rendering. @@ -256,7 +256,7 @@ To access search params in [Pages](/docs/app/api-reference/file-conventions/page #### Layouts -Unlike Pages, [Layouts](/docs/app/api-reference/file-conventions/layout) (Server Components) **do not** receive the `searchParams` prop. This is because a shared layout is [not re-rendered during navigation](/docs/app/building-your-application/routing#partial-rendering) which could lead to stale `searchParams` between navigations. View [detailed explanation](/docs/app/api-reference/file-conventions/layout#layouts-do-not-receive-searchparams). +Unlike Pages, [Layouts](/docs/app/api-reference/file-conventions/layout) (Server Components) **do not** receive the `searchParams` prop. This is because a shared layout is [not re-rendered during navigation](/docs/app/building-your-application/routing/linking-and-navigating#3-partial-rendering) which could lead to stale `searchParams` between navigations. View [detailed explanation](/docs/app/api-reference/file-conventions/layout#layouts-do-not-receive-searchparams). Instead, use the Page [`searchParams`](/docs/app/api-reference/file-conventions/page) prop or the [`useSearchParams`](/docs/app/api-reference/functions/use-search-params) hook in a Client Component, which is re-rendered on the client with the latest `searchParams`. diff --git a/docs/02-app/02-api-reference/05-next-config-js/incrementalCacheHandlerPath.mdx b/docs/02-app/02-api-reference/05-next-config-js/incrementalCacheHandlerPath.mdx index a5c608cbdb273..50c0c8e3d771e 100644 --- a/docs/02-app/02-api-reference/05-next-config-js/incrementalCacheHandlerPath.mdx +++ b/docs/02-app/02-api-reference/05-next-config-js/incrementalCacheHandlerPath.mdx @@ -3,7 +3,7 @@ title: incrementalCacheHandlerPath description: Configure the Next.js cache used for storing and revalidating data. --- -In Next.js, the [default cache handler](/docs/app/building-your-application/data-fetching/caching) uses the filesystem cache. This requires no configuration, however, you can customize the cache handler by using the `incrementalCacheHandlerPath` field in `next.config.js`. +In Next.js, the [default cache handler](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating uses the filesystem cache. This requires no configuration, however, you can customize the cache handler by using the `incrementalCacheHandlerPath` field in `next.config.js`. ```js filename="next.config.js" module.exports = { @@ -64,4 +64,4 @@ Returns `Promise`. | --------- | -------- | ---------------------------- | | `tag` | `string` | The cache tag to revalidate. | -Returns `Promise`. Learn more about [revalidating data](/docs/app/building-your-application/data-fetching/revalidating) or the [`revalidateTag()`](/docs/app/api-reference/functions/revalidateTag) function. +Returns `Promise`. Learn more about [revalidating data](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) or the [`revalidateTag()`](/docs/app/api-reference/functions/revalidateTag) function. diff --git a/docs/02-app/02-api-reference/05-next-config-js/serverComponentsExternalPackages.mdx b/docs/02-app/02-api-reference/05-next-config-js/serverComponentsExternalPackages.mdx index 8d35f76e2e7a2..b290b3621dd01 100644 --- a/docs/02-app/02-api-reference/05-next-config-js/serverComponentsExternalPackages.mdx +++ b/docs/02-app/02-api-reference/05-next-config-js/serverComponentsExternalPackages.mdx @@ -3,7 +3,7 @@ title: serverComponentsExternalPackages description: Opt-out specific dependencies from the Server Components bundling and use native Node.js `require`. --- -Dependencies used inside [Server Components](/docs/getting-started/react-essentials#server-components) and [Route Handlers](/docs/app/building-your-application/routing/router-handlers) will automatically be bundled by Next.js. +Dependencies used inside [Server Components](/docs/getting-started/react-essentials#server-components) and [Route Handlers](/docs/app/building-your-application/routing/route-handlers) will automatically be bundled by Next.js. If a dependency is using Node.js specific features, you can choose to opt-out specific dependencies from the Server Components bundling and use native Node.js `require`. diff --git a/docs/03-pages/01-building-your-application/01-routing/07-api-routes.mdx b/docs/03-pages/01-building-your-application/01-routing/07-api-routes.mdx index 74a9ff29dbdc0..8fb64564aeba9 100644 --- a/docs/03-pages/01-building-your-application/01-routing/07-api-routes.mdx +++ b/docs/03-pages/01-building-your-application/01-routing/07-api-routes.mdx @@ -16,7 +16,7 @@ description: Next.js supports API Routes, which allow you to build your API with -> **Good to know**: If you are using the App Router, you can use [Server Components](/docs/app/building-your-application/data-fetching/fetching) or [Route Handlers](/docs/app/building-your-application/routing/router-handlers) instead of API Routes. +> **Good to know**: If you are using the App Router, you can use [Server Components](/docs/app/building-your-application/data-fetching/fetching-caching-and-revalidating) or [Route Handlers](/docs/app/building-your-application/routing/route-handlers) instead of API Routes. diff --git a/errors/api-routes-static-export.mdx b/errors/api-routes-static-export.mdx index 541902b61cc0b..5351cbe7653bb 100644 --- a/errors/api-routes-static-export.mdx +++ b/errors/api-routes-static-export.mdx @@ -15,9 +15,9 @@ To resolve this issue, you have two main options: 1. Use the `next build` command instead of `next export` if you're deploying your application on platforms that don't require `next export`. For example, [Vercel](https://vercel.com) is a popular hosting platform for Next.js applications that supports this feature. 2. If you still need to use `next export`, make sure to remove any paths that use API routes from your `exportPathMap` in your `next.config.js` file. -3. Consider [incrementally adopting the App Router](/docs/app/building-your-application/upgrading/app-router-migration), which supportes [Route Handlers](/docs/app/building-your-application/routing/router-handlers). These "API Routes" can be used to create endpoints that can be statically exported in your application. +3. Consider [incrementally adopting the App Router](/docs/app/building-your-application/upgrading/app-router-migration), which supportes [Route Handlers](/docs/app/building-your-application/routing/route-handlers). These "API Routes" can be used to create endpoints that can be statically exported in your application. ## Useful Links - [Static HTML export](/docs/pages/building-your-application/deploying/static-exports) - Learn more about how you can create a static HTML export of your Next.js application. -- [Route Handlers](/docs/app/building-your-application/routing/router-handlers) - Learn more about how you can use Route Handlers to create endpoints that can be statically exported in your application. +- [Route Handlers](/docs/app/building-your-application/routing/route-handlers) - Learn more about how you can use Route Handlers to create endpoints that can be statically exported in your application. diff --git a/errors/app-static-to-dynamic-error.mdx b/errors/app-static-to-dynamic-error.mdx index 03424b988c08e..e7a9ee5641b75 100644 --- a/errors/app-static-to-dynamic-error.mdx +++ b/errors/app-static-to-dynamic-error.mdx @@ -19,5 +19,5 @@ To resolve this issue, you have two main options: ## Useful Links -- [Static and Dynamic Rendering](/docs/app/building-your-application/rendering/static-and-dynamic-rendering) - Learn more about the differences between static and dynamic rendering in Next.js. -- [Dynamic Functions](/docs/app/building-your-application/data-fetching/fetching#server-component-functions) - Understand more about the usage of dynamic server functions in your Next.js application. +- [Static and Dynamic Rendering](/docs/app/building-your-application/rendering/static-and-dynamic) - Learn more about the differences between static and dynamic rendering in Next.js. +- [Dynamic Functions](/docs/app/building-your-application/rendering/static-and-dynamic#dynamic-functions) - Understand more about the usage of dynamic server functions in your Next.js application.