PortableText missing "image" component type in blockcontent
PortableText [components.type] is missing “image”
And then I follow this page to try to define custom component type:
https://www.sanity.io/guides/ultimate-guide-for-customising-portable-text-from-schema-to-react-component
I’ve added this, but all I got is rendering error
😞 Would appreciate it if someone can point me in the right direction.
const Body = (props)=> {
// we pass the content, width & height of the images into each instance of the Body component
// content is our array of blocks
const { content, imgWidth, imgHeight } = props;
const customBlockComponents = {
// first we tackle our custom block types
types: {
image: ({value}) => {
// we need to get the image source url, and since @sanity/image-url will give us optimised images for each instance we use it
const imgUrl = urlForImage(value.assset).height(imgHeight).width(imgWidth).url()
return <Image
width={imgWidth}
height={imgHeight}
alt={value.alt}
src={imgUrl}
sizes="100vw"
priority={false}
/>
},
},
// then we define how the annotations should be rendered
marks: {
link: ({children, value}) => {
const rel = !value.href.startsWith('/') ? 'noreferrer noopener' : undefined
return (
<a href={value.href} target='_blank' rel={rel}>
{children}
</a>
)
},
internalLink: ({children, value}) => {
return (
<a href={value.href}>
{children}
</a>
)
},
},
}
return <PortableText
value={content}
components={customBlockComponents}
/>
}I can see the issue! There's a typo in your code that's causing the problem. In your image component, you have:
const imgUrl = urlForImage(value.assset).height(imgHeight).width(imgWidth).url()Notice value.assset - it should be value.asset (with one 's'). This typo means the image URL builder can't find the image reference, which is causing your rendering error.
Here's the corrected version:
const customBlockComponents = {
types: {
image: ({value}) => {
// Fixed: value.asset instead of value.assset
const imgUrl = urlForImage(value.asset)
.height(imgHeight)
.width(imgWidth)
.url()
return <Image
width={imgWidth}
height={imgHeight}
alt={value.alt}
src={imgUrl}
sizes="100vw"
priority={false}
/>
},
},
marks: {
link: ({children, value}) => {
const rel = !value.href.startsWith('/') ? 'noreferrer noopener' : undefined
return (
<a href={value.href} target='_blank' rel={rel}>
{children}
</a>
)
},
internalLink: ({children, value}) => {
return (
<a href={value.href}>
{children}
</a>
)
},
},
}A few additional tips:
Add error handling: Consider adding a check to ensure the asset exists before trying to build the URL:
if (!value?.asset) return null;Alt text fallback: Make sure your image schema includes an
altfield, or provide a fallback:alt={value.alt || 'Image'}Check your urlForImage setup: Make sure your
urlForImagefunction is properly configured with your Sanity project details (you can use @sanity/image-url for this).
The approach you're following from that guide is correct - this typo is just preventing it from working! Fix that and you should be good to go. 😊
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.