Sanity block content rendering spaces as &nbsp in Next.js with GraphQL
I can see you're hitting a common issue with the older block-content-to-react library! The good news is there's a straightforward solution, but first, an important heads-up: block-content-to-react is deprecated, and you should migrate to the newer @portabletext/react library, which is the officially supported solution.
The Issue
The (non-breaking space) problem you're seeing typically happens when there's HTML entity encoding happening in your render chain. The spaces in your Portable Text content are being converted to entities, and then those entities are being displayed literally instead of being rendered as actual spaces.
Quick fix for block-content-to-react:
Try passing the serializers prop with a custom text serializer that handles the text nodes properly:
import BlockContent from '@sanity/block-content-to-react'
const serializers = {
marks: {
// Add any custom mark serializers you need
}
}
<BlockContent
blocks={yourContent}
serializers={serializers}
projectId="your-project-id"
dataset="your-dataset"
/>Make sure you're passing the projectId and dataset props to the BlockContent component - missing these can sometimes cause rendering issues.
Better Solution: Migrate to @portabletext/react
Since you just started this morning, now is the perfect time to switch to the modern approach! Here's how:
- Install the new package:
npm install @portabletext/react- Update your component:
import { PortableText } from '@portabletext/react'
// In your component
<PortableText value={yourContent} />The new library handles text rendering much more reliably and has better TypeScript support. If you need custom components (for images, code blocks, etc.), the syntax is slightly different:
const components = {
types: {
image: ({value}) => <img src={value.url} alt={value.alt} />
},
marks: {
link: ({value, children}) => <a href={value.href}>{children}</a>
}
}
<PortableText value={yourContent} components={components} />Note the key differences when migrating from block-content-to-react:
serializers→componentsnode→valuein your custom component propsblocks→valueas the prop name
Using with Next.js
Since you're fetching via GraphQL for static props, your setup should work fine with either library. Just make sure you're querying the Portable Text field correctly in your GraphQL query - it should return the full block array structure.
If you continue having issues after switching to @portabletext/react, check that your GROQ/GraphQL query is returning the Portable Text in its raw array format, not as a pre-serialized string.
Welcome to Sanity, and congrats on moving your portfolio to a proper CMS! 🎉
Show original thread12 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.