Sanity block content rendering spaces as &nbsp in Next.js with GraphQL

12 replies
Last updated: Mar 8, 2021
Hello,I am very New to
Sanity.io , just started using it this morning. Set up a studio to refactor my Portfolio project that was using JSON data until now, but ready to move to a CMS now. Set up some schemas to start refactoring.Using Next.js on the frontend, and fetching GraphQL for static props. Using block-content-to-react for rendering.

Having an issue on rendering the paragraphs on the front-end. Spaces are replaced with &nbsp , stretching out my layout. JSON data seems to be coming in fine. To be honest, I don`t even know where to start looking for this issue.
AI Update

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:

  1. Install the new package:
npm install @portabletext/react
  1. 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:

  • serializerscomponents
  • nodevalue in your custom component props
  • blocksvalue as 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 thread
12 replies
Hi and welcome, Gabor!
How did you get your JSON data into Sanity? Was this manually typed in the Studio or did you import it?
Thank you Geoff!I set up the document and objects for Sanity studio, then manually typed in all the fields. Most of my existing stuff is placeholder or need rewriting, will be doing the whole thing manually.

Tried fetching with fetch API and Axios, they both deliver, but ending up with the same result.

In the meantime, I refactored using react-portable-text. Works nicely, much cleaner, but the non-breaking spaces are still there instead of spaces.
Very interesting. The closest I can get to replicating this is by using option-spaces in the portable text editor. If I copy that text and encode it, the option-spaces are reflected as &amp;nbsp; entities. However, those non-breaking spaces don’t show on my front end nor when I inspect in the Studio.
The only thing left might be your serializer, but I don’t even know how you’d get it to convert spaces to &amp;nbsp; entities.
Yeah, finding it confusing as well, I didn`t even see anybody mention anything like that, was googling all afternoon. I tried manually rendering the individual text fields in simple paragraphs, but issue stayed. JSON object also seems fine in the console.
For serializer, I only use custom highlights at this point, but the issue is there, even with a single object, no marks.

Thanks anyway :)
Do you get the entities outside of your highlight mark?
Highlights render nicely, between them the line even breaks. It is just the normal text misbehaving, that is what renders with nbsp
The closest I can get to replicating this is by using option-spaces in the portable text editor. If I copy that text and encode it, the option-spaces are reflected as &amp;nbsp; entities. However, those non-breaking spaces don’t show on my front end nor when I inspect in the Studio.
Hi Gabor. I realized that when I try this in Chrome, I get the same result as you (the &amp;nbsp; entities show in the dev tools). I’m back to thinking it’s in the JSON, not the serializer.
Interesting. I tried in Chrome, Firefox and Edge, same issue for me in all three.
Sorry, all I meant was that the &amp;nbsp; didn’t show up in FF dev tools for me, but they did in Chrome.
Oh, I see. It shows up in Edge as well, not in Firefox
Hello there,Issue solved, it wasn`t an issue on Sanity side. Apparently, the data I manually copy-pasted to the studio replaced spaces with non-breaking-space html entities. If I go through the text manually, and replace spaces. or write it there from scratch, works without an issue.
Thanks for your help :)
Glad to hear you got it resolved, Gabor!

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.

Was this answer helpful?