htmlToBlocks JSDOM parseHtml error in Next.js 13 server-side API
I have tried JSDOM(html).window.document instead of JSDOM(html) but this raise another error. "- error ReferenceError: window is not defined" after looping thru all of the elements of the html
Any ideas?
const convertedBlocks = htmlToBlocks(content, blockContentType, {
parseHtml: (html) => new JSDOM(html),
rules: [
// Special rule for code blocks
{
deserialize(el, next, block) {
console.log('el: ', el);
if (el.tagName?.toLowerCase() === 'img') {
const src = el.getAttribute('src');
const alt = el.getAttribute('alt');
console.log('el: ', el);
// Create block object for each image
const imageBlock = {
_type: 'image',
asset: {
_type: 'reference',
_ref: 'toReplace' + index
}
// Add any other relevant metadata fields
};
imageLibrary.push(src);
index++;
return block(imageBlock);
}
// Continue with default conversion for other elements
return undefined;
}
}
]
});- error ReferenceError: window is not defined
at Module.getRandomValues (webpack-internal:///(sc_server)/./node_modules/get-random-values-esm/index.mjs:7:5)
at whatwgRNG (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:185:37)
at randomKey (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:193:12)
at normalizeBlock (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:1145:15)
at eval (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:1201:56)
at Array.map (<anonymous>)
at htmlToBlocks (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:1201:43)
at eval (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:55:102)
at new Promise (<anonymous>)
at convertHtmlToBlocks (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:49:12)
at eval (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:110:34)
at new Promise (<anonymous>)
at writeNewSolutionData (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:105:12)
at POST (webpack-internal:///(sc_server)/./src/app/api/submit-design/route.js:13:110)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37)- error TypeError: Cannot read properties of undefined (reading 'firstElementChild')
at preprocessGDocs (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:426:18)
at eval (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:463:9)
at Array.forEach (<anonymous>)
at preprocess (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:462:19)
at HtmlDeserializer.parseHtml (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:1131:25)
at HtmlDeserializer.deserialize (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:951:30)
at htmlToBlocks (webpack-internal:///(sc_server)/./node_modules/@sanity/block-tools/lib/index.js:1201:25)
at eval (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:55:102)
at new Promise (<anonymous>)
at convertHtmlToBlocks (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:49:12)
at eval (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:109:34)
at new Promise (<anonymous>)
at writeNewSolutionData (webpack-internal:///(sc_server)/./lib/sanityDatabaseFunctions.js:104:12)
at POST (webpack-internal:///(sc_server)/./src/app/api/submit-design/route.js:13:110)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37)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.
Show original thread3 replies
Was this answer helpful?
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.