How to Create a Field where Editors can add a Soft Break to a String

2 replies
Last updated: Aug 13, 2020
Good morning. I need to create a field where editors can add a soft break to a string. This means I cant use the
string
type. I've tried using the
block
type and removing all options from it other than allowing the h1 style. Is there a way to reduce set h1 as the default style rather than 'normal'? Alternatively, is there a better way to do what I'm trying to do (the size of the block input is not ideal for a single title)?
AI Update

I understand you need a field where editors can add soft breaks (line breaks without creating new paragraphs) to a string, and you've been experimenting with the block type but finding the UI too large for a single title.

Unfortunately, Portable Text doesn't natively support soft breaks (the <br> equivalent from HTML). When users press Shift+Enter in the Portable Text editor, it creates a new block rather than a soft break within the same block. This is a known limitation - there's a GitHub issue #2572 that discusses this exact problem with line breaks in Portable Text.

For setting a default block style to h1, you can use the initialValue property on your field. Here's how:

defineField({
  name: 'title',
  type: 'array',
  of: [
    {
      type: 'block',
      styles: [
        {title: 'H1', value: 'h1'}
      ],
      lists: [],
      marks: {
        decorators: [],
        annotations: []
      }
    }
  ],
  initialValue: [
    {
      _type: 'block',
      style: 'h1',
      children: [{_type: 'span', text: ''}]
    }
  ]
})

This sets the default style to h1 when a new document is created, though editors can still change it if you haven't removed the style selector entirely. You can learn more about this in the Initial Value Templates documentation.

However, I'd recommend a different approach for your use case:

Since you need soft breaks in what's essentially a title/heading field, consider using the text type instead of block. The text type supports multi-line strings and you can control the textarea size:

defineField({
  name: 'title',
  type: 'text',
  rows: 2 // Controls the visible height of the textarea
})

The text type gives you a simple textarea where Enter creates actual line breaks (soft breaks) in the string, which is exactly what you need. When rendering on your frontend, these line breaks will be preserved as \n characters that you can convert to <br> tags.

If you absolutely need the h1 semantic meaning stored with the content and still want soft breaks, you might need to implement a custom input component, but the text type with rows is the simplest and most practical solution for titles with line breaks.

Morning JD, have you tried our
text
type? This is ideal for a basic string expected to contain multiple lines. You can also control the number of rows in the rendered textarea by setting the
rows
property (default: 10). https://www.sanity.io/docs/text-type
Oh nice one. This will work for my purposes. 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?