Portable Text not rendering spacing, new lines, and headers correctly

11 replies
Last updated: Jan 28, 2026
Hey everyone, first time posting here!
I followed the Sanity tutorial for making a blog with Sanity, React and Next:

https://www.sanity.io/blog/build-your-own-blog-with-sanity-and-next-js
This is my first time integrating Sanity into any project, so I basically stuck to the guide as is.

I'm having an issue with the @sanity/block-content-to-react package and rendering the Portable Text the way I format it in Sanity. (Some things come through, like bold and italics, but most things dont, like spacing, or new lines or any of the headers (H1, H2, etc).

Here's the link to my site:
https://ellies-lego-land.vercel.app/
Here's the link to my Github where I import <BlockContent />:
https://github.com/jamesncox/ellies-lego-land/blob/main/web/pages/post/%5Bslug%5D.js
I've read through the docs on block-content-to-react, but honestly, I'm having trouble making sense of it.

Thanks in advance for any help!
AI Update

I can help you with this! The issue you're experiencing is because @sanity/block-content-to-react is deprecated and has been replaced by the newer @portabletext/react library. The older package has some limitations and doesn't handle all Portable Text features as reliably as the modern replacement.

Looking at your code on GitHub, you're using the deprecated package, which is likely why headers, spacing, and line breaks aren't rendering properly while basic marks like bold and italics still work.

Here's how to fix it:

1. Install the new package:

npm install @portabletext/react

2. Update your imports in [slug].js:

// Replace this:
import BlockContent from "@sanity/block-content-to-react";

// With this:
import { PortableText } from "@portabletext/react";

3. Update how you render the content:

// Replace this:
<BlockContent
  blocks={body}
  projectId="your-project-id"
  dataset="production"
/>

// With this:
<PortableText value={body} />

The new library automatically handles all standard Portable Text elements (headings, paragraphs, lists, line breaks, etc.) out of the box without needing to pass projectId or dataset.

If you need custom styling:

You can pass custom components to control how different elements render:

const components = {
  block: {
    h1: ({children}) => <h1 className="text-4xl font-bold">{children}</h1>,
    h2: ({children}) => <h2 className="text-3xl font-bold">{children}</h2>,
    normal: ({children}) => <p className="my-4">{children}</p>,
  },
  marks: {
    link: ({value, children}) => <a href={value.href} className="text-blue-500">{children}</a>,
  }
}

<PortableText value={body} components={components} />

Key differences in the migration:

  • The prop name changed from blocks to value
  • The node prop in custom serializers is now called value
  • Components are organized under block, marks, list, and types categories

This should fix all your rendering issues on your Ellies Lego Land site! The @portabletext/react library properly handles spacing, line breaks, and all heading levels that the older package struggled with. Check out the ultimate guide for customizing Portable Text if you need more advanced customization options.

Show original thread
11 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.

Was this answer helpful?