Issue with using JSDOM in htmlToBlocks function for server-side API
Based on the issue you're experiencing, the problem stems from @sanity/block-tools using get-random-values-esm which expects browser globals like window that don't exist in Node.js server environments. This is a known issue when using htmlToBlocks in Next.js 13 server-side API routes.
The solution that worked for others is to add a package override to your package.json:
{
"overrides": {
"get-random-values-esm": "npm:get-random-values@^1.2.2"
}
}If you're using pnpm, use the pnpm.overrides field instead:
{
"pnpm": {
"overrides": {
"get-random-values-esm": "npm:get-random-values@^1.2.2"
}
}
}Or for Yarn, use resolutions:
{
"resolutions": {
"get-random-values-esm": "npm:get-random-values@^1.2.2"
}
}After adding this override, delete your node_modules folder and lock file, then reinstall your dependencies:
rm -rf node_modules package-lock.json
npm installWhy this works: Next.js resolves get-random-values-esm to the ESM version which references window.crypto. The override forces it to use the older CommonJS version (get-random-values) which properly detects the Node.js environment and uses Node's crypto module instead.
Also make sure your parseHtml option returns the document object:
parseHtml: (html) => new JSDOM(html).window.documentThis was a common pain point with @sanity/block-tools in server-side environments, and the package override is the most reliable workaround until the underlying dependency is updated.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.