Styling Portable Text blocks with @portabletext/react components

8 replies
Last updated: Nov 30, 2025
Hello again everyone! I am trying to style a portable text component with '@portabletext/react' and I can't make any sense of the documentation...
I have my components defined like so.

const ptComponents = {
    block: {
      h1: ({ value }: any) => {
        return <h1 className="whiteText">{value}</h1>;
      },
      p: ({ value }: any) => {
        return <p className="whiteText">{value}</p>;
      },
    },
  };
And I am passing the components to the Portable Text Component here.

<PortableText value={project.fulldesc} components={ptComponents} />
The styles are not being applied though. What am I doing wrong? I seriously can't make out how to do this:
https://github.com/portabletext/react-portabletext
AI Update

I can see your issue! The problem is that you're using value in your component props, but for block-level elements like headings and paragraphs, you should be using children instead. The value prop contains the raw block data, while children contains the already-rendered text content.

Here's the corrected code:

const ptComponents = {
  block: {
    h1: ({ children }) => {
      return <h1 className="whiteText">{children}</h1>;
    },
    p: ({ children }) => {
      return <p className="whiteText">{children}</p>;
    },
  },
};

The key difference: children instead of value.

Why this matters

When @portabletext/react processes block-level elements (like paragraphs and headings), it:

  1. Processes all the inline content (text, marks, annotations)
  2. Passes the rendered result as children to your custom component
  3. The value prop contains the raw JSON structure of the block, which isn't what you want to render

Additional tips

If you need access to the raw block data (for example, to check custom fields), you can use both:

h1: ({ children, value }) => {
  console.log(value); // Raw block data
  return <h1 className="whiteText">{children}</h1>;
}

You can also apply different styles based on the block's properties:

block: {
  normal: ({ children }) => <p className="whiteText">{children}</p>,
  h1: ({ children }) => <h1 className="whiteText text-4xl">{children}</h1>,
  h2: ({ children }) => <h2 className="whiteText text-3xl">{children}</h2>,
}

For more complex styling scenarios, check out the ultimate guide for customising Portable Text which covers everything from schema to React components.

Show original thread
8 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?