
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeI can see you're working with @sanity/block-content-to-react, but I should mention upfront that this library is deprecated. The modern replacement is @portabletext/react, which has better support and a cleaner API.
However, to answer your specific question about lists in @sanity/block-content-to-react:
The key thing to understand is that you don't serialize <ul> or <ol> directly. Instead, you need to serialize list and listItem types. The library handles the wrapping <ul> or <ol> elements automatically based on the list style.
Here's how to properly handle lists:
import BlockContent from '@sanity/block-content-to-react'
const serializers = {
list: (props) => {
const {type} = props
const bullet = type === 'bullet'
if (bullet) {
return <ul className="custom-bullet-list">{props.children}</ul>
}
return <ol className="custom-number-list">{props.children}</ol>
},
listItem: (props) => {
return <li className="custom-list-item">{props.children}</li>
}
}
<BlockContent
blocks={content}
serializers={serializers}
/>The list serializer receives:
type: Either 'bullet' or 'number'children: The rendered list itemslevel: The nesting level (for nested lists)The listItem serializer receives:
children: The content of the list itemThe library automatically groups consecutive list items with the same type into a single list wrapper, which is why you serialize the list container separately from the individual items.
If you're starting fresh or can refactor, I'd strongly recommend migrating to @portabletext/react. The syntax is cleaner:
import {PortableText} from '@portabletext/react'
const components = {
list: {
bullet: ({children}) => <ul className="custom-bullet">{children}</ul>,
number: ({children}) => <ol className="custom-number">{children}</ol>
},
listItem: ({children}) => <li className="custom-item">{children}</li>
}
<PortableText value={content} components={components} />The main differences: node becomes value, and the structure is more organized with separate categories for list, marks, types, and block.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store