Portable Text Editor: Superscript/Subscript decorators not displaying correctly

4 replies
Last updated: Nov 29, 2025
Hey, I am following https://www.sanity.io/docs/customizing-the-portable-text-editor#e6401a8fe843 to try and add super and sub script options to the editor, but nothing is displaying correctly.
import {GrSubscript, GrSuperscript} from 'react-icons/gr'
const SuperscriptDecorator = props => (
  <span style={{backgroundColor: 'yellow'}}>{props.children}</span>
)
const SubscriptDecorator = props => (
  <span style={{backgroundColor: 'yellow'}}>{props.children}</span>
)
...
...
marks: {
          decorators: [
            {title: 'Strong', value: 'strong'},
            {title: 'Emphasis', value: 'em'},
            {title: 'Underline', value: 'underline'},
            {title: 'Superscript', value: 'sup', icon: GrSuperscript, component: SuperscriptDecorator},
            {title: 'Subscript', value: 'sub', icon: GrSubscript}
          ],
}
When I have just the icons, sanity runs but the icons aren't being imported (see screenshot). When I also add in the component to display the superscript, I get an error in the studio (screenshot). Anyone have any ideas what I'm doing wrong? This is sanity v2.35.0
AI Update

I can see the issue! You're using Sanity v2.35.0, and there are two problems with your code:

The Icon Issue

React Icons components need to be wrapped in a function that returns the component. Try this:

marks: {
  decorators: [
    {title: 'Strong', value: 'strong'},
    {title: 'Emphasis', value: 'em'},
    {title: 'Underline', value: 'underline'},
    {
      title: 'Superscript', 
      value: 'sup', 
      icon: () => <GrSuperscript />,  // Wrap in a function
      component: SuperscriptDecorator
    },
    {
      title: 'Subscript', 
      value: 'sub', 
      icon: () => <GrSubscript />,  // Wrap in a function
      component: SubscriptDecorator
    }
  ],
}

The Component Issue

Your decorator components also need to render the actual HTML elements (<sup> and <sub>), not just styling wrappers:

const SuperscriptDecorator = props => (
  <sup>{props.children}</sup>
)

const SubscriptDecorator = props => (
  <sub>{props.children}</sub>
)

The yellow background styling you had was just for testing, but it won't create the actual superscript/subscript effect. The <sup> and <sub> HTML elements are what actually position the text correctly in the editor.

Complete Working Example for v2

import {GrSubscript, GrSuperscript} from 'react-icons/gr'

const SuperscriptDecorator = props => (
  <sup>{props.children}</sup>
)

const SubscriptDecorator = props => (
  <sub>{props.children}</sub>
)

// In your schema:
marks: {
  decorators: [
    {title: 'Strong', value: 'strong'},
    {title: 'Emphasis', value: 'em'},
    {title: 'Underline', value: 'underline'},
    {
      title: 'Superscript', 
      value: 'sup', 
      icon: () => <GrSuperscript />,
      component: SuperscriptDecorator
    },
    {
      title: 'Subscript', 
      value: 'sub', 
      icon: () => <GrSubscript />,
      component: SubscriptDecorator
    }
  ],
}

Note: If you were on Sanity v3, the syntax would use blockEditor.icon and blockEditor.render instead, as shown in this community answer, but that's not what you need for v2.

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