👀 See Sanity in action: Watch product demo now →

How to Deal With Spans and Decorators when Rendering Portable Text using the Serializer

5 replies
Last updated: May 12, 2021
I’m trying to render portable Text using the serializer. My problem is how to deal with the spans that have <strong> decorators. If I render the normal spans in a div there will be a linebreak after every span, including strong span (meaning in the middle of a sentence). And if I render it in a span, all my paragraphs within the same block will render as one single paragraph.
May 11, 2021, 6:02 AM
I'm using block-content-to-react. At the moment my serializer looks like this:

const serializers = {
 
types: {
  
block: (props: any) => (
   
props.children.map((child: any, index: React.Key) => {
    
switch (props.node.style) {
     
case 'h2':
      
return <MarginTopFour><MarginBottomOne><h2 key={index}>{child}</h2></MarginBottomOne></MarginTopFour>;
     
case 'h3':
      
return <MarginTopThree><MarginBottomOne><h3 key={index}>{child}</h3></MarginBottomOne></MarginTopThree>;
     
case 'normal':
      
return <span key={index}>{child}</span>;
     
default:
      
return <span key={index}>{child}</span>;
    
}
   
})
  
),
 
},
 
marks: {
    
strong: (props: any) => <DarkSpan>{props.children}</DarkSpan>,
 
},

};
May 11, 2021, 5:52 PM
This code puts all the different paragraphs together as one. If I change
case: 'normal'
to return a div instead of a span, the spans with strong decorator will also be on a individual line.
May 11, 2021, 5:56 PM
Does
<DarkSpan />
render inline? If it does, that part looks good.
I may be off track but I’m not sure that normal should return a span
or a div. I’d be curious what you get if you just return
{child}
. I’m also looking at this example and wondering what you get if you
return BlockContent.defaultSerializers.types.block({ child })
.
May 11, 2021, 6:13 PM
Yes, <DarkSpan /> render inline.
If I return {child} without div or span it work fine so do the code from codeSandbox example. But I want to put some styling on the rendered text. Can I combine it with styled components, that's what I'm trying to do? If yes, how do I do? If no, how can I style the text?
May 12, 2021, 5:40 AM
We've solved the problem. When we map through the children we affect every single span instead of the whole paragraph. So if we return {props.children} instead of {child} it works perfectly.
case 'normal':

return <p>{props.children}</p>;
Thanks
user A
for looking into this.
May 12, 2021, 8:10 AM

Sanity.io – build remarkable experiences at scale

Sanity is a customizable solution that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.