Issue with displaying images in a block on Next.js application resolved with the help of custom portable text and Sanity's image URL documentation.
I can help you with this! The issue you're experiencing is a common one when working with Portable Text in React. When you're using react-portable-text, images aren't automatically rendered - you need to define custom serializers (components) to tell the library how to handle image blocks.
The first thing to note is that react-portable-text is actually an older, community-maintained library. I'd recommend switching to @portabletext/react, which is the official library from Sanity and has better support for TypeScript and Next.js.
With @portabletext/react (Recommended)
First, install the official library:
npm install @portabletext/react @sanity/image-urlThen create custom serializers for your images:
import { PortableText } from '@portabletext/react'
import imageUrlBuilder from '@sanity/image-url'
import { SanityImageSource } from '@sanity/image-url/lib/types/types'
// Configure your image builder
const builder = imageUrlBuilder({
projectId: 'your-project-id',
dataset: 'your-dataset'
})
function urlFor(source: SanityImageSource) {
return builder.image(source)
}
// Define your custom components
const ptComponents = {
types: {
image: ({ value }: any) => {
if (!value?.asset?._ref) {
return null
}
return (
<img
src={urlFor(value).width(800).url()}
alt={value.alt || ' '}
loading="lazy"
/>
)
}
}
}
// Use it in your component
export default function MyComponent({ content }: { content: any }) {
return <PortableText value={content} components={ptComponents} />
}With react-portable-text (Your Current Setup)
If you want to stick with react-portable-text, you need to add serializers:
import PortableText from 'react-portable-text'
import imageUrlBuilder from '@sanity/image-url'
const builder = imageUrlBuilder({
projectId: 'your-project-id',
dataset: 'your-dataset'
})
<PortableText
content={yourContent}
serializers={{
image: ({ value }: any) => (
<img
src={builder.image(value).width(800).url()}
alt={value.alt || ' '}
/>
)
}}
/>Important Notes
Install @sanity/image-url: You'll need this package to generate proper image URLs from Sanity's image references.
Check your schema: Make sure your Portable Text field includes the image type:
{ name: 'body', type: 'array', of: [ { type: 'block' }, { type: 'image' } // This is crucial! ] }The "unknown type image" warning means your serializer isn't being recognized. The custom component configuration above should fix this.
I'd strongly recommend migrating to @portabletext/react as it's the actively maintained solution with better TypeScript support and follows modern React patterns. The main API difference is that it uses value instead of node props in serializers, but it's more reliable for Next.js projects.
For more details on customizing Portable Text rendering, check out Sanity's comprehensive guide.
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.