Trouble applying custom styles in rich text editor to live site
Ah, this is a common point of confusion! Customizing styles in the Sanity Studio rich text editor only affects how content looks in the Studio - it doesn't automatically apply those styles to your frontend. You need to handle rendering separately on your website.
The Two-Part Solution
1. Studio Styling (what you've already done) - This is just for the editor experience. When you customize decorators with blockEditor.render, that only affects how content creators see styled text while editing.
2. Frontend Rendering (what you're missing) - You need to configure how Portable Text renders on your actual website using a serializer/component library.
How to Render Custom Styles on Your Frontend
Depending on your framework, you'll use different libraries:
For React/Next.js, use @portabletext/react:
import {PortableText} from '@portabletext/react'
const components = {
marks: {
// Custom decorator
sup: ({children}) => <sup>{children}</sup>,
sub: ({children}) => <sub>{children}</sub>,
// Built-in decorators (if you want custom rendering)
strong: ({children}) => <strong className="font-bold">{children}</strong>,
// Link annotation (for your hyperlink question)
link: ({value, children}) => {
const target = (value?.href || '').startsWith('http') ? '_blank' : undefined
return (
<a href={value?.href} target={target} rel={target === '_blank' ? 'noopener' : undefined}>
{children}
</a>
)
},
},
block: {
h1: ({children}) => <h1 className="text-4xl">{children}</h1>,
// ... other block styles
}
}
// In your component
<PortableText value={content} components={components} />For other frameworks:
- Vue/Nuxt: @portabletext/vue
- Svelte: @portabletext/svelte
- HTML/vanilla JS: @portabletext/to-html
Controlling Link Rendering
For your hyperlink question - yes, you absolutely control the DOM rendering! In the marks.link component above, you define exactly how links render. You can add classes, control target attributes, add analytics tracking, etc.
The key insight: Portable Text is structured data. The Studio shows one representation, but your frontend can render it however you want. The Studio's blockEditor.render and your frontend's serializer components are completely independent.
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.