mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
c2b4c0815c
This PRs unifies the caching story across the docs, making Cache Components the happy path, while still providing guidance to users in the old model. However, instead of explaining the old model and its caching layers, we've created a new guide focusing on what APIs to use and when. This follow-up PR aligns terminology across the docs: https://github.com/vercel/next.js/pull/90589 ## IA updates Getting Started section: - Improves Getting Started progression: - **Before:** CC → Fetching Data → Updating Data → Caching and Revalidating (old and new model mixed) - **After:** Fetching Data (Dynamic) → Mutating Data (Dynamic) → Caching with CC (Prerendering) → Revalidating with CC. - New: `caching.mdx` (CC-first) - Structure: - Enabling Cache Components - Data vs UI-level caching - Working with request time APIs - Passing request values to cached functions - Working with non-deterministic operations - Working with synchronous operations - How rendering works (PPR and static shell story) - New: `revalidating.mdx` (CC-first) - Explains how to use `cacheLife` and `cacheTag` Guides Section: - New: `caching-and-revalidating.mdx` (Previous Model) - For users who are not using CC, includes `fetch` options and route segment config - Moves route segment config options that don't apply to CC from API reference to this guide (for easy archiving in the future). - New: `migrating-to-cache-components.mdx` (WIP) - Del: `caching.mdx` 😌 ## Terminology We should remove caching layers from the docs. Users only needed to be exposed to them when they were configured independently, but the new CC APIs work across layers. To make it easier to review this PR, I'm consolidating terminology and fixing broken links in a new PR: https://github.com/vercel/next.js/pull/90589 --------- Co-authored-by: Vercel <vercel[bot]@users.noreply.github.com> Co-authored-by: Joseph <joseph.chamochumbi@vercel.com>
93 lines
3.4 KiB
Plaintext
93 lines
3.4 KiB
Plaintext
---
|
|
title: Dynamic APIs are Asynchronous
|
|
description: Learn more about why accessing certain APIs synchronously now warns.
|
|
---
|
|
|
|
## Why This Warning Occurred
|
|
|
|
Somewhere in your code you used an API that opts into [dynamic rendering](/docs/app/glossary#dynamic-rendering).
|
|
|
|
Dynamic APIs are:
|
|
|
|
- The `params` and `searchParams` props that get provided to pages, layouts, metadata APIs, and route handlers.
|
|
- `cookies()`, `draftMode()`, and `headers()` from `next/headers`
|
|
|
|
In Next 15, these APIs have been made asynchronous. You can read more about this in the Next.js 15 [Upgrade Guide](/docs/app/guides/upgrading/version-15).
|
|
|
|
For example, the following code will issue a warning:
|
|
|
|
```jsx filename="app/[id]/page.js"
|
|
function Page({ params }) {
|
|
// direct access of `params.id`.
|
|
return <p>ID: {params.id}</p>
|
|
}
|
|
```
|
|
|
|
This also includes enumerating (e.g. `{...params}`, or `Object.keys(params)`) or iterating over the return
|
|
value of these APIs (e.g. `[...headers()]` or `for (const cookie of cookies())`, or explicitly with `cookies()[Symbol.iterator]()`).
|
|
|
|
## Possible Ways to Fix It
|
|
|
|
The [`next-async-request-api` codemod](/docs/app/guides/upgrading/codemods#next-async-request-api) can fix many of these cases automatically:
|
|
|
|
```bash filename="Terminal"
|
|
npx @next/codemod@canary next-async-request-api .
|
|
```
|
|
|
|
The codemod cannot cover all cases, so you may need to manually adjust some code.
|
|
|
|
If the warning occurred on the Server (e.g. a route handler, or a Server Component),
|
|
you must `await` the dynamic API to access its properties:
|
|
|
|
```jsx filename="app/[id]/page.js"
|
|
async function Page({ params }) {
|
|
// asynchronous access of `params.id`.
|
|
const { id } = await params
|
|
return <p>ID: {id}</p>
|
|
}
|
|
```
|
|
|
|
If the warning occurred in a synchronous component (e.g. a Client component),
|
|
you must use `React.use()` to unwrap the Promise first:
|
|
|
|
```jsx filename="app/[id]/page.js"
|
|
'use client'
|
|
import * as React from 'react'
|
|
|
|
function Page({ params }) {
|
|
// asynchronous access of `params.id`.
|
|
const { id } = React.use(params)
|
|
return <p>ID: {id}</p>
|
|
}
|
|
```
|
|
|
|
### Unmigratable Cases
|
|
|
|
If Next.js codemod found anything that is not able to be migrated by the codemod, it will leave a comment with `@next-codemod-error` prefix and the suggested action, for example:
|
|
In this case, you need to manually await the call to `cookies()`, and change the function to async. Then refactor the usages of the function to be properly awaited:
|
|
|
|
```ts
|
|
export function MyCookiesComponent() {
|
|
const c =
|
|
/* @next-codemod-error Manually await this call and refactor the function to be async */
|
|
cookies()
|
|
return c.get('name')
|
|
}
|
|
```
|
|
|
|
### Enforced Migration with Linter
|
|
|
|
If you didn't address the comments that starting with `@next-codemod-error` left by the codemod, Next.js will error in both dev and build to enforce you to address the issues.
|
|
You can review the changes and follow the suggestion in the comments. You can either make the necessary changes and remove the comment, or replace the comment prefix `@next-codemod-error` with `@next-codemod-ignore`
|
|
If there's no action to be taken, the comment prefix `@next-codemod-ignore` will bypass the build error.
|
|
|
|
```diff
|
|
- /* @next-codemod-error <suggested message> */
|
|
+ /* @next-codemod-ignore */
|
|
```
|
|
|
|
> **Good to know**:
|
|
>
|
|
> You can delay unwrapping the Promise (either with `await` or `React.use`) until you actually need to consume the value.
|
|
> This will allow Next.js to statically render more of your page.
|