Migrating from react-portable-text to @portabletext/react value prop
Your code looks correct! The value={post.body} prop is indeed the right approach when migrating from react-portable-text (which used content) to the newer @portabletext/react (which uses value).
Based on your GROQ query and component setup, the issue is likely in how you're handling the image type in your custom components. The @portabletext/react library passes props differently than the old library.
Here's what needs to change in your image component:
<PortableText
value={post.body}
components={{
types: {
image: ({ value }) => { // Changed from destructuring asset directly
return (
<figure className="inline-image">
<img
src={urlFor(value.asset).width(value.width || 800).fit("max").url()}
alt={value.alt || ''}
/>
<figcaption>
{value.caption && <span className="float-left">{value.caption}</span>}
{value.credit && (
<i className="float-right">Photo credit: {value.credit}</i>
)}
</figcaption>
</figure>
);
},
},
// ... rest of your components
}}
/>The key difference: in @portabletext/react, custom type components receive a value prop that contains all the block's data, whereas the old library passed properties directly. So you need to access value.asset, value.alt, value.caption, etc.
Also note that you were referencing caption and credit variables that weren't defined - you'll need to access them from value.caption and value.credit.
Your GROQ query looks good for fetching the body content. The value={post.body} is correct - it should be the array of blocks returned from your query.
If you're still getting errors, check:
- That
post.bodyis actually defined and is an array - The exact error message - it will help identify if there's a specific block type or mark causing issues
- That you've installed the correct package:
npm install @portabletext/react(notreact-portable-text)
The Portable Text introduction guide and beginner's guide have more examples of custom serializers if you need additional reference.
Show original thread28 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.