Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 21 additions & 11 deletions docs/01-app/01-getting-started/06-cache-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ When a user visits a route:

> **🎥 Watch:** Why PPR and how it works → [YouTube (10 minutes)](https://www.youtube.com/watch?v=MTcPrTIBkpA).

## How it Works
## How it works

Cache Components gives you three key tools to control rendering:

Expand All @@ -61,6 +61,7 @@ Some data is only available at runtime when an actual user makes a request. APIs
- [`cookies`](/docs/app/api-reference/functions/cookies)
- [`headers`](/docs/app/api-reference/functions/headers)
- [`searchParams` prop](/docs/app/api-reference/file-conventions/page#searchparams-optional)
- [`params` prop](/docs/app/api-reference/file-conventions/page#params-optional) - This is runtime data unless you provide at least one example value through [`generateStaticParams`](/docs/app/api-reference/functions/generate-static-params). When provided, those specific param values are treated as static for prerendered paths, while other values remain runtime

### 2. Suspense for dynamic data

Expand All @@ -71,21 +72,20 @@ Dynamic data like [`fetch`](/docs/app/api-reference/functions/fetch) calls or da
- [`fetch`](/docs/app/api-reference/functions/fetch) requests
- Database queries
- [`connection`](/docs/app/api-reference/functions/connection)
- [`unstable_noStore`](/docs/app/api-reference/functions/unstable_noStore)

### 3. Cached data with `use cache`

Add `use cache` to any Server Component to make it cached and include it in the pre-rendered shell. You cannot use runtime APIs from inside a cached component. You can also mark utility functions as `use cache` and call them from Server Components.

```tsx
'use cache'
export async function getProducts() {
'use cache'
const data = await db.query('SELECT * FROM products')
return data
}
```

## Using Suspense Boundaries
## Using Suspense boundaries

React [Suspense](https://react.dev/reference/react/Suspense) boundaries let you define what fallback UI to use when it wraps dynamic or runtime data.

Expand Down Expand Up @@ -137,17 +137,27 @@ async function DynamicContent() {

At build time, Next.js pre-renders the static content and the `fallback` UI, while the dynamic content is postponed until a user requests the route.

Wrapping a component in `Suspense` doesn't make it dynamic; your API usage does. `Suspense` acts as a boundary that encapsulates dynamic content and enables streaming.
> **Good to know**: Wrapping a component in `Suspense` doesn't make it dynamic; your API usage does. `Suspense` acts as a boundary that encapsulates dynamic content and enables streaming.

### Missing Suspense boundaries

Cache Components enforces that dynamic code must be wrapped in a `Suspense` boundary. If you forget, you'll see this error:
Cache Components enforces that dynamic code must be wrapped in a `Suspense` boundary. If you forget, you'll see the [Uncached data was accessed outside of `<Suspense>`](https://nextjs.org/docs/messages/blocking-route) error:

> Uncached data was accessed outside of `<Suspense>`
> **Uncached data was accessed outside of `<Suspense>`**
>
> This delays the entire page from rendering, resulting in a slow user
> experience. Next.js uses this error to ensure your app loads instantly
> on every navigation.
>
> To fix this, you can either:
>
> **Wrap the component in a `<Suspense>`** boundary. This allows Next.js to stream its contents to the user as soon as it's ready, without blocking the rest of the app.
>
> or
>
> **Move the asynchronous await into a Cache Component("use cache")**. This allows Next.js to statically prerender the component as part of the HTML document, so it's instantly visible to the user.
>
> Note that request-specific information, such as params, cookies, and headers, is not available during static prerendering, so it must be wrapped in `<Suspense>`.

This error helps prevent a situation where, instead of getting a static shell instantly, users would hit a blocking runtime render with nothing to show. To fix it, add a `Suspense` boundary or use `use cache` to cache the work instead.

Expand Down Expand Up @@ -181,7 +191,7 @@ To reduce network overhead, the full response, including static HTML and streame

While `Suspense` boundaries manage dynamic content, the [`use cache`](/docs/app/api-reference/directives/use-cache) directive is available for caching data or computations that don't change often.

### Basic Usage
### Basic usage

Add `use cache` to cache a page, component, or async function, and define a lifetime with [`cacheLife`](/docs/app/api-reference/functions/cacheLife):

Expand Down Expand Up @@ -251,7 +261,7 @@ export async function CachedWrapper({ children }) {

You must not pass dynamic or runtime data into `use cache` functions unless you avoid introspecting them. Passing values from `cookies()`, `headers()`, or other runtime APIs as arguments will cause errors, as the cache key cannot be determined at pre-render time.

### Tagging and Revalidating
### Tagging and revalidating

Tag cached data with [`cacheTag`](/docs/app/api-reference/functions/cacheTag) and revalidate it after mutations using [`updateTag`](/docs/app/api-reference/functions/updateTag) in Server Actions for immediate updates, or [`revalidateTag`](/docs/app/api-reference/functions/revalidateTag) delay in updates are acceptable.

Expand Down Expand Up @@ -321,7 +331,7 @@ const nextConfig = {
module.exports = nextConfig
```

### Effect on Route Segment Config
### Effect on route segment config

When Cache Components is enabled, several route segment config options are no longer needed or supported. Here's what changes and how to migrate:

Expand Down Expand Up @@ -412,7 +422,7 @@ export default async function Page() {
}
```

## Before vs. After Cache Components
## Before vs. after Cache Components

Understanding how Cache Components changes your mental model:

Expand Down
17 changes: 13 additions & 4 deletions docs/01-app/03-api-reference/04-functions/use-pathname.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ description: API Reference for the usePathname hook.

`usePathname` is a **Client Component** hook that lets you read the current URL's **pathname**.

> **Good to know**: When [`cacheComponents`](/docs/app/api-reference/config/next-config-js/cacheComponents) is enabled `usePathname` may require a `Suspense` boundary around it if your route has a dynamic param. If you use `generateStaticParams` the `Suspense` boundary is optional

```tsx filename="app/example-client-component.tsx" switcher
'use client'

Expand Down Expand Up @@ -34,10 +36,17 @@ For example, a Client Component with `usePathname` will be rendered into HTML on
> **Good to know**:
>
> - Reading the current URL from a [Server Component](/docs/app/getting-started/server-and-client-components) is not supported. This design is intentional to support layout state being preserved across page navigations.
> - Compatibility mode:
> - `usePathname` can return `null` when a [fallback route](/docs/pages/api-reference/functions/get-static-paths#fallback-true) is being rendered or when a `pages` directory page has been [automatically statically optimized](/docs/pages/building-your-application/rendering/automatic-static-optimization) by Next.js and the router is not ready.
> - When using `usePathname` with rewrites in [`next.config`](/docs/app/api-reference/config/next-config-js/rewrites) or [`Proxy`](/docs/app/api-reference/file-conventions/proxy), `useState` and `useEffect` must also be used in order to avoid hydration mismatch errors.
> - Next.js will automatically update your types if it detects both an `app` and `pages` directory in your project.
> - If your page is being statically pre-rendered and your app has [rewrites](/docs/app/api-reference/config/next-config-js/rewrites) in `next.config` or a [Proxy](/docs/app/api-reference/file-conventions/proxy) file, reading the pathname with `usePathname()` can result in hydration mismatch errors—because the initial value comes from the server and may not match the actual browser pathname after routing. See our [example](#avoid-hydration-mismatch-with-rewrites) for a way to mitigate this issue.

<details>

<summary>Compatibility with Pages Router</summary>

If you have components that use `usePathname` and they are imported into routes within the Pages Router, be aware that `usePathname` may return `null` if the router is not yet initialized. This can occur in cases such as [fallback routes](/docs/pages/api-reference/functions/get-static-paths#fallback-true) or during [Automatic Static Optimization](https://nextjs.org/docs/pages/building-your-application/rendering/static#automatic-static-optimization) in the Pages Router.

To enhance compatibility between routing systems, if your project contains both an `app` and a `pages` directory, Next.js will automatically adjust the return type of `usePathname`.

</details>

## Parameters

Expand Down
Loading