errors/next-prerender-crypto.mdx
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().
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:
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:
async function getCachedData() {
"use cache"
const token = crypto.getRandomUUID()
return db.query(token, ...)
}
export default async function Page() {
const data = await getCachedData();
return ...
}
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:
import { generateKeySync } from 'node:crypto'
export default async function Page() {
const key = generateKeySync('hmac', { ... })
const digestedData = await digestDataWithKey(data, key);
return ...
}
After:
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 ...
}
await connection() at request-timeIf 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:
export default async function Page() {
const uuid = crypto.randomUUID()
return <RequestId id={uuid} />
}
After:
import { connection } from 'next/server'
export default async function Page() {
await connection()
const uuid = crypto.randomUUID()
return <RequestId id={uuid} />
}