Some checks failed
Test examples / Test Examples (20) (push) Has been cancelled
Test examples / Test Examples (22) (push) Has been cancelled
Lock Threads / action (push) Has been cancelled
Trigger Release / start (push) Has been cancelled
Stale issue handler / stale (push) Has been cancelled
Update Font Data / create-pull-request (push) Has been cancelled
build-and-deploy / deploy-target (push) Has been cancelled
build-and-deploy / build (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-musl - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-unknown-linux-gnu - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-pc-windows-msvc - node@16 (push) Has been cancelled
build-and-deploy / stable - aarch64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / stable - x86_64-apple-darwin - node@16 (push) Has been cancelled
build-and-deploy / build-wasm (nodejs) (push) Has been cancelled
build-and-deploy / build-wasm (web) (push) Has been cancelled
build-and-deploy / Deploy preview tarball (push) Has been cancelled
build-and-deploy / Potentially publish release (push) Has been cancelled
build-and-deploy / publish-turbopack-npm-packages (push) Has been cancelled
build-and-deploy / Deploy examples (push) Has been cancelled
build-and-deploy / thank you, build (push) Has been cancelled
build-and-deploy / Upload Turbopack Bytesize metrics to Datadog (push) Has been cancelled
Rspack Next.js development integration tests / Rspack integration tests (push) Has been cancelled
Rspack Next.js production integration tests / Rspack integration tests (push) Has been cancelled
Turbopack Next.js development integration tests / Next.js integration tests (push) Has been cancelled
Turbopack Next.js production integration tests / Next.js integration tests (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack development test manifest (push) Has been cancelled
Update Rspack test manifest / Update and upload Rspack production test manifest (push) Has been cancelled
Upload bundler test manifests to areweturboyet.com / Upload test results (push) Has been cancelled
Update React / create-pull-request (push) Has been cancelled
test-e2e-project-reset-cron / reset-test-project (push) Has been cancelled
Notify about the top 15 issues/PRs/feature requests (most reacted) in the last 90 days / run (push) Has been cancelled
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.
|