How to fix "Unknown block type undefined" error in Portable Text with Sanity?
The error you're seeing happens because your GROQ query is returning an object structure that doesn't match what Portable Text expects. The issue is in how you're filtering your blockContent array.
When you do 'hero': blockContent[_type == 'hero'], this returns an array of hero blocks, not the blocks themselves in Portable Text format. Then when you pass props.main to <PortableText>, it's receiving an object like { hero: [...], platforms: [...] } rather than a proper Portable Text array of blocks.
Here are two ways to fix this:
Option 1: Pass the arrays separately (recommended)
Instead of passing the entire main object to a single PortableText component, render each section separately:
const main = await sanity.fetch(groq`
*[_type == "pages" && pageSlug.current == $pageSlug][0]{
'hero': blockContent[_type == 'hero'],
'platforms': blockContent[_type == 'platforms']
}
`, {pageSlug})
// Then render:
<>
<PortableText components={ptComponents} value={main.hero} />
<PortableText components={ptComponents} value={main.platforms} />
</>Option 2: Keep the full blockContent structure
If you want to render everything together in order, fetch the entire blockContent array and let PortableText handle it:
const main = await sanity.fetch(groq`
*[_type == "pages" && pageSlug.current == $pageSlug][0]{
blockContent
}
`, {pageSlug})
// Then render:
<PortableText components={ptComponents} value={main.blockContent} />The key issue is that Portable Text expects an array of blocks, not an object with nested arrays. Each block in the array should have a _type property that matches your component definitions (hero, platforms, etc.).
Also note: Your GROQ filter syntax should use && instead of chaining multiple [][]. The corrected syntax is *[_type == "pages" && pageSlug.current == $pageSlug][0].
Show original thread16 replies
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.