How to render a special formatted inline text in blockContent in Sanity.io

20 replies
Last updated: May 19, 2020
if I have a
type
in my blockContent that I’d like to render as sort of inline text just with some special formatting - is that possible? I originally made it an annotation but that’s clearly to lightweight. I want to manage these as documents but as a doc, it’s a full-width element in the editor. Would like it to show jsut like this
May 19, 2020, 2:51 PM
so, I’d like to insert a “keyword” with value of
EDITOR
and be able to continue typing text after that.
May 19, 2020, 2:52 PM
I can’t seem to get this implementation to flow inside some text, it needs to be on a new line of it’s own
May 19, 2020, 2:54 PM
Hi User, I hope I’m following along correctly here. Is adding these as objects instead an option to you? Or otherwise as a reference to a document? If so, you could try this:

blockContent.js
export default {
  name: 'blockContent',
  type: 'array',
  title: 'Block content',
  of: [
    {
      type: 'block',
      title: 'Block',
      styles: [...],
      lists: [...],
      marks: {
        decorators: [...],
        annotations: [...]
      },
      of: [{type: 'keywordRef'}]
    }
  ]
}

keywordRef.js
export default {
  name: 'keywordRef',
  type: 'object',
  title: 'Keyword',
  fields: [
    {
      name: 'keyword',
      type: 'reference',
      to: [
        {
          type: 'keyword'
        }
      ]
    }
  ],
  preview: {
    select: {
      title: 'keyword.title'
    }
  }
}
May 19, 2020, 3:04 PM
Hi User, I hope I’m following along correctly here. Is adding these as objects instead an option to you? Or otherwise as a reference to a document? If so, you could try this:

blockContent.js
export default {
  name: 'blockContent',
  type: 'array',
  title: 'Block content',
  of: [
    {
      type: 'block',
      title: 'Block',
      styles: [...],
      lists: [...],
      marks: {
        decorators: [...],
        annotations: [...]
      },
      of: [{type: 'keywordRef'}]
    }
  ]
}

keywordRef.js
export default {
  name: 'keywordRef',
  type: 'object',
  title: 'Keyword',
  fields: [
    {
      name: 'keyword',
      type: 'reference',
      to: [
        {
          type: 'keyword'
        }
      ]
    }
  ],
  preview: {
    select: {
      title: 'keyword.title'
    }
  }
}
May 19, 2020, 3:04 PM
I actually have defined them as a document, so is the
preview
element the bit that will make this sort of appear as text instead of this large element? Trying to understand the terms and thought process - still a little hard to know what I need to look for! 😄
May 19, 2020, 3:06 PM
If they’re now defined as documents, i.e. they already exist when a Studio user wants to insert them as a keyword, then you could go with the above approach to simply let them set a reference to the document. That reference is inline and is an object, but what it refers to can be a document.
If you mean for the Studio user to write a new, non-existing keyword right there in the editor, then this approach won’t work I’m afraid.

In terms of the preview, it lets you define exactly what info is shown inline in the editor - in this case, the referred-to keyword document’s title. Hope that helps clear things up a bit?
🙂
May 19, 2020, 3:09 PM
so looks like nesting another
of
inside the block array gets me a lot closer, and now it certainly looks better
May 19, 2020, 3:13 PM
I’ll reference a document I think, we’ll reuse these keywords elsewhere most likely
May 19, 2020, 3:13 PM
That makes sense. It can be a little bit of a hassle to define these separately, especially at the start when there are not many keywords yet perhaps. But it makes things more tidy and query-able afterwards. Hopefully we can add a ‘create reference in place’ functionality along the way 😉
May 19, 2020, 3:14 PM
ok, so to clarify, there’s not a way to “create” a new keyword while in the block editor, I would just need to create the doc first?
May 19, 2020, 3:15 PM
Not if keyword is a
document
type, not yet at least. It’s a much requested feature to be able to create these ‘on the fly’ wherever you would reference them.
If
keyword is an
object
type then, yes, you can create these directly in the editor (but they won’t be reusable in other places).
May 19, 2020, 3:20 PM
ok that’s fine with me, good to know that’s the limitation. Last thing, for the editor button, how do I change the “Reference to Keyword” text?
May 19, 2020, 3:23 PM
You can customise this by adding something like
title: 'Keyword'
to the reference object.
May 19, 2020, 3:27 PM
keywords.js

import { FaBolt } from 'react-icons/fa';

export default {
  name: 'keyword',
  title: 'Keyword',
  type: 'document',
  icon: FaBolt,
  preview: {
    select: {
      title: 'keyword',
    },
  },
  fields: [
    {
      name: 'keyword',
      title: 'Keyword',
      type: 'string',
    },
    {
      name: 'description',
      title: 'Description',
      type: 'array',
      of: [
        {
          title: 'Block',
          type: 'block',
          styles: [{ title: 'Normal', value: 'normal' }],
          lists: [],
        },
      ],
    },
  ],
};
May 19, 2020, 3:44 PM
blockContent.js
import React from 'react';

export default {
  title: 'Block Content',
  name: 'blockContent',
  type: 'array',
  of: [
    {
      title: 'Block',
      type: 'block',
      // Styles let you set what your user can mark up blocks with. These
      // corrensponds with HTML tags, but you can set any title or value
      // you want and decide how you want to deal with it where you want to
      // use your content.
      styles: [
        { title: 'Normal', value: 'normal' },
        { title: 'H1', value: 'h1' },
        { title: 'H2', value: 'h2' },
        { title: 'H3', value: 'h3' },
        { title: 'H4', value: 'h4' },
        { title: 'H5', value: 'h5' },
        { title: 'H6', value: 'h6' },
        { title: 'Quote', value: 'blockquote' },
      ],
      lists: [
        { title: 'Bullet', value: 'bullet' },
        { title: 'Numbered', value: 'number' },
      ],
      // Marks let you mark up inline text in the block editor.
      marks: {
        // Decorators usually describe a single property – e.g. a typographic
        // preference or highlighting by editors.
        decorators: [
          { title: 'Strong', value: 'strong' },
          { title: 'Emphasis', value: 'em' },
          { title: 'Underline', value: 'underline' },
          // { title: 'Keyword', value: 'keyword', icon: FaBolt, render: keyword },
        ],
        // Annotations can be any object structure – e.g. a link or a footnote.
        annotations: [
          // { type: 'twitter' },
          // { type: 'externalLink' },
          // { type: 'internalLink' },
          // { type: 'keyword' },
        ],
      },
      of: [
        {
          type: 'reference',
          to: [
            {
              type: 'keyword',
            },
          ],
        },
      ],
    },
    // You can add additional types here. Note that you can't use
    // primitive types such as 'string' and 'number' in the same array
    // as a block type.
    {
      type: 'figure',
    },
  ],
};
May 19, 2020, 3:45 PM
I still have that long description for the keyword item in the editor
May 19, 2020, 3:45 PM
And if you change it to this instead?
...
      of: [
        {
          type: 'reference',
          title: 'Keyword',
          to: [
            {
              type: 'keyword',
            },
          ],
        },
      ],
...
May 19, 2020, 4:23 PM
A more flexible way of achieving the above is creating an additional type as explained earlier in the thread:
export default {
  name: 'keywordRef',
  type: 'object',
  title: 'Keyword',
  fields: [
    {
      name: 'keyword',
      type: 'reference',
      to: [
        {
          type: 'keyword'
        }
      ]
    }
  ],
  preview: {
    select: {
      title: 'keyword.keyword'
    }
  }
}
And including it as
of: [{type: 'keywordRef'}]
instead. That way, you can have some different settings (previews in particular) for your keyword reference in block content, and for your keyword document list elsewhere in the Studio. Hope it’s a bit clear what I mean with that 😉
May 19, 2020, 4:27 PM
great that’s perfect! Making a bit more sense now how I can customize at each layer, but it’s a lot to take in.. thanks!
May 19, 2020, 5:29 PM
Agreed, there’s plenty of ground to cover. Hang in there 🙂
May 19, 2020, 5:31 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?