How Can I Format Text in the Block Content Editor to Reflect the Custom Style?
Yes, it's absolutely possible to customize how text appears in the Portable Text Editor to visually reflect your custom styles! The key is using the component property when defining your custom decorators or block styles in your schema.
When you create a custom decorator or block style, you can specify both an icon and a component to control how the styled content appears in the editor itself. This gives your editors a visual preview of what they're creating, making the editing experience much more intuitive.
Custom Decorators
For custom decorators (like highlight, superscript, subscript), you pass a React component to the component property. Here's a practical example from the official documentation on customizing the Portable Text Editor:
import React from 'react'
const HighlightIcon = () => (
<span style={{ fontWeight: 'bold' }}>H</span>
)
const HighlightDecorator = props => (
<span style={{ backgroundColor: 'yellow' }}>{props.children}</span>
)
export default {
name: 'content',
title: 'Content',
type: 'array',
of: [
{
type: 'block',
marks: {
decorators: [
{ title: 'Strong', value: 'strong' },
{ title: 'Emphasis', value: 'em' },
{ title: 'Code', value: 'code' },
{
title: 'Highlight',
value: 'highlight',
icon: HighlightIcon,
component: HighlightDecorator // This renders the visual style
}
]
}
}
]
}The component receives the text content as props.children and you wrap it in whatever JSX/styling you need to represent that style visually.
Custom Block Styles
The same approach works for custom block styles. Here's an example of creating a custom "title" style with different typography:
import React from 'react'
const TitleStyle = props => (
<span style={{fontFamily: 'Garamond', fontSize: '2em'}}>
{props.children}
</span>
)
export default {
name: 'content',
title: 'Content',
type: 'array',
of: [
{
type: 'block',
styles: [
{title: 'Normal', value: 'normal'},
{title: 'H1', value: 'h1'},
{
title: 'Title',
value: 'title',
component: TitleStyle // Applies custom style in the editor
},
]
}
]
}Custom Annotations
For annotations (like links), you can also customize their appearance in the editor using the components.annotation property:
import { LaunchIcon } from '@sanity/icons'
const ExternalLinkRenderer = props => (
<span>
{props.renderDefault(props)}
<a contentEditable={false} href={props.value.href}>
<LaunchIcon />
</a>
</span>
)
export default {
name: 'content',
type: 'array',
of: [
{
type: 'block',
marks: {
annotations: [
{
name: 'link',
type: 'object',
title: 'link',
fields: [{ name: 'url', type: 'url' }],
components: {
annotation: ExternalLinkRenderer
}
}
]
}
}
]
}This visual feedback makes it much easier for content editors to understand what they're creating without having to preview on the frontend. For more comprehensive examples and patterns, check out the Ultimate Guide on customizing Portable Text and the common Portable Text Editor patterns documentation.
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.