Files
next.js/errors/next-prerender-crypto.mdx
T
Josh StoryandGitHub 035a12ea8e [dynamicIO] Document client component remediations for sync IO (#79787)
When you use sync IO in the client in a way that needs to be fixed we
currently still just provide you with the explanation for server
components. The fixes when sync IO happens in the client are not the
same as when they happen in a server component so this update adds
client specific documentation for these situations.

Namely, the key difference is that on the server you can add caching
through "use cache" and this is not available to you in the client. sync
IO in general is (going to be) allowed in client components broadly as
long as Next.js has a fallback UI to prerender. This means that "fixing"
sync IO access in the client will usually be solved by wrapping in a
Suspense boundary. The alternative is to move the sync IO out of render
or move it to the server where it can be cached.
2025-06-03 16:44:51 -07:00

106 lines
3.3 KiB
Plaintext

---
title: Cannot access `crypto.getRandomValue()`, `crypto.randomUUID()`, or another web or node crypto API that generates random values synchronously in a Server Component
---
## Why This Error Occurred
An API that produces a random value synchronously from the Web Crypto API or from Node's `crypto` API was called outside of a `"use cache"` scope and without first calling `await connection()`. Random values that are produced synchronously must either be inside a `"use cache"` scope or be preceded with `await connection()` to explicitly communicate to Next.js whether the random values produced can be reused across many requests (cached) or if they must be unique per Request (`await connection()`).
If the API used has an async version you can also switch to that instead of using `await connection()`.
## Possible Ways to Fix It
### Cache the token value
If you are generating a token to talk to a database that itself should be cached move the token generation inside the `"use cache"`.
Before:
```jsx filename="app/page.js"
async function getCachedData(token: string) {
"use cache"
return db.query(token, ...)
}
export default async function Page() {
const token = crypto.getRandomUUID()
const data = await getCachedData(token);
return ...
}
```
After:
```jsx filename="app/page.js"
async function getCachedData() {
"use cache"
const token = crypto.getRandomUUID()
return db.query(token, ...)
}
export default async function Page() {
const data = await getCachedData();
return ...
}
```
### Use an async API at request-time
If you require this random value to be unique per Request and an async version of the API exists switch to it instead. Also ensure that there is a parent Suspense boundary that defines a fallback UI Next.js can use while rendering this component on each Request.
Before:
```jsx filename="app/page.js"
import { generateKeySync } from 'node:crypto'
export default async function Page() {
const key = generateKeySync('hmac', { ... })
const digestedData = await digestDataWithKey(data, key);
return ...
}
```
After:
```jsx filename="app/page.js"
import { generateKey } from 'node:crypto'
export default async function Page() {
const key = await new Promise(resolve => generateKey('hmac', { ... }, key => resolve(key)))
const digestedData = await digestDataWithKey(data, key);
return ...
}
```
### Use `await connection()` at request-time
If you require this random value to be unique per Request and an async version of the API does not exist, call `await connection()`. Also ensure that there is a parent Suspense boundary that defines a fallback UI Next.js can use while rendering this component on each Request.
Before:
```jsx filename="app/page.js"
export default async function Page() {
const uuid = crypto.randomUUID()
return <RequestId id={uuid} />
}
```
After:
```jsx filename="app/page.js"
import { connection } from 'next/server'
export default async function Page() {
await connection()
const uuid = crypto.randomUUID()
return <RequestId id={uuid} />
}
```
## Useful Links
- [`connection` function](/docs/app/api-reference/functions/connection)
- [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API)
- [Node Crypto API](https://nodejs.org/docs/latest/api/crypto.html)
- [`Suspense` React API](https://react.dev/reference/react/Suspense)