Custom rich text editor styles not showing on live site

16 replies
Last updated: Nov 29, 2025
I've modified the styles available in rich text editor and I can see that the custom styles are applied in rich text editor. But in live site, it isn't working!
I'm not sure why the UI is not applied in the site! Similarly, I want to control the rendering DOMs too (say, I want to render the hyperlink content within
<a>
tag).
cc:
user E
user T
user M
user A

Here is the UI:
AI Update

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:

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.

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