Adding bold/italics to string field without full block editor

3 replies
Last updated: Jul 21, 2023
Hey all, looking for a schema setup where I can add bold, & italics to a title/string field. Current setup is to use an array/block and then limit it to 1 line via validation. This works but looks like overkill. Anyway to improve this setup, loose aim at getting the WYSIWYG height to that of a string field and maybe disabling the ability to hit return?
AI Update

Your current approach is actually pretty solid! Using an array with a single block type and validation to limit it to one line is the standard way to add bold/italic formatting to a title field in Sanity. However, there are a few things you can do to make it feel less like overkill:

Making it more title-like

According to the block type documentation, you can use the oneLine option to restrict the Portable Text input to a single line:

{
  name: 'title',
  title: 'Title',
  type: 'array',
  of: [
    {
      type: 'block',
      styles: [],  // Remove style dropdown (no H1, H2, etc)
      lists: [],   // Remove list options
      marks: {
        decorators: [
          {title: 'Strong', value: 'strong'},
          {title: 'Emphasis', value: 'em'}
        ],
        annotations: []  // Remove link option
      },
      options: {
        oneLine: true  // This prevents hitting return!
      }
    }
  ],
  validation: Rule => Rule.required().max(1)
}

The key improvements here:

  1. oneLine: true - This disables the ability to hit return and keeps everything on a single line
  2. styles: [] - Removes the style dropdown (Normal, H1-H6, blockquote)
  3. lists: [] - Removes bullet/numbered list options
  4. annotations: [] - Removes the link annotation if you don't need it

Styling the editor height

Unfortunately, there's no built-in option to reduce the WYSIWYG height to match a string field exactly. The Portable Text Editor has a minimum height by default. However, you can use custom components to add custom CSS:

{
  type: 'block',
  // ... other config
  components: {
    input: (props) => (
      <div style={{ minHeight: 'auto' }}>
        {props.renderDefault(props)}
      </div>
    )
  }
}

This approach gives you inline formatting in what feels much more like a title field, while still being technically correct as Portable Text.

Show original thread
3 replies
{
      name: 'headingBlock',
      title: 'Hero Title block',
      // fieldset: 'hero',
      of: [
        {
          type: 'block',
          styles: [{title: 'Normal', value: 'normal'}],
          lists: [],
          marks: {
            decorators: [
              {title: 'Strong', value: 'strong'},
              {title: 'Emphasis', value: 'em'},
            ],
          },
        },
      ],
      type: 'array',
      validation: (Rule) =>
        Rule.custom((value, {document}) => {
          if (value && value?.length > 1) {
            return 'This is a title and so can only be one line.';
          }
          return true;
        }),
    },
I don’t think there’s a clean way to do this, unfortunately.
No worries, this setup works fine, it was just the details I was getting caught up on. Thanks!

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?