Custom Portable Text decorator not showing icon/style in Sanity v3

6 replies
Last updated: Dec 2, 2025
Hi everyone, I work on Sanity v3 and I want to edit my portable text editor. I followed the documentation (https://www.sanity.io/docs/customizing-the-portable-text-editor#92d92c3189a3 ) but it doesn’t work (look on the picture).
Here’s my code :

{
  title: "Titre du block",
  name: "titleBlock",
  type: "array",
  of: [{ 
    type: "block",
    marks: {
      decorators: [
        { title: "Strong", value: "strong" },
        { title: "Emphasis", value: "em" },
        { title: "Code", value: "code" },
        { title: "Underline", value: "underline" },
        { title: "Strike", value: "strike-through" },
        {
          title: 'Highlight',
          value: 'highlight',
          icon: () => <span style={{fontWeight: 'bold'}}>H</span>,
          component: (props: any) => <span style={{ backgroundColor: 'yellow' }}>{props.children}</span>,
        }
      ],
    }
  }],
  group: "text",
  validation: (Rule: any) => Rule.required(),
},
My file is a tsx due to vite build who can’t work with js file (the doc use js file, how ?)

How can I add my icon and my style in the custom component ?

Thank’s for the help
🙏
AI Update

I can see your code structure is actually correct according to the official Sanity documentation! The pattern of using icon and component directly on the decorator object is the right approach for Sanity v3. However, there are a few things that might be causing issues. Let me help you troubleshoot:

Your code structure is correct, but here are some common issues and solutions:

1. Import React properly

Make sure you have React imported at the top of your file since you're using JSX:

import React from 'react'

2. Icon component needs to return valid JSX

Your icon function should return a proper React element. Try this:

{
  title: 'Highlight',
  value: 'highlight',
  icon: () => <span style={{fontWeight: 'bold'}}>H</span>,
  component: (props: any) => (
    <span style={{ backgroundColor: 'yellow' }}>{props.children}</span>
  ),
}

3. Alternative: Use a proper icon from @sanity/icons

Instead of an inline function, you could import an icon from the @sanity/icons package:

import { HighlightIcon } from '@sanity/icons'

// Then in your decorator:
{
  title: 'Highlight',
  value: 'highlight',
  icon: HighlightIcon,
  component: (props: any) => (
    <span style={{ backgroundColor: 'yellow' }}>{props.children}</span>
  ),
}

4. Complete working example

Here's a complete working example based on the official documentation:

import React from 'react'

const HighlightIcon = () => (
  <span style={{ fontWeight: 'bold' }}>H</span>
)

const HighlightDecorator = (props: any) => (
  <span style={{ backgroundColor: 'yellow' }}>{props.children}</span>
)

export default {
  title: "Titre du block",
  name: "titleBlock",
  type: "array",
  of: [{ 
    type: "block",
    marks: {
      decorators: [
        { title: "Strong", value: "strong" },
        { title: "Emphasis", value: "em" },
        { title: "Code", value: "code" },
        { title: "Underline", value: "underline" },
        { title: "Strike", value: "strike-through" },
        {
          title: 'Highlight',
          value: 'highlight',
          icon: HighlightIcon,
          component: HighlightDecorator,
        }
      ],
    }
  }],
  group: "text",
  validation: (Rule: any) => Rule.required(),
}

5. Regarding TypeScript/TSX files

You're absolutely right to use .tsx files! Sanity v3 works perfectly with TypeScript. The documentation examples use .js for simplicity, but .tsx is actually the recommended approach for type safety. This is not causing your issue.

6. Restart your dev server

After making schema changes, make sure to restart your Sanity Studio dev server:

npm run dev

or if you're using the newer commands:

npx sanity dev

Common troubleshooting steps:

  1. Check your browser console for any error messages - this is crucial for understanding what's going wrong
  2. Make sure you're on Sanity Studio v3 (check your package.json for sanity version)
  3. Clear your browser cache and hard refresh (Ctrl+Shift+R or Cmd+Shift+R)
  4. Try upgrading Sanity if you're on an older v3 version: npx sanity upgrade

Possible issues based on the pattern:

Without seeing the picture you mentioned, the most common issues are:

  • Icon not showing: This usually means the icon component isn't returning valid JSX or React isn't imported
  • Styling not applying: Make sure the component prop receives and renders props.children
  • Button not appearing: Check if all decorators are showing or just the custom one is missing

The pattern you're using matches the official documentation exactly, so if it's still not working after these adjustments, please share any error messages from the console and I can help further! 🙏

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