Unlock seamless workflows and faster delivery with our latest releases - Join the deep dive

How to show portable text in Sanity.io preview when title is not added

16 replies
Last updated: May 30, 2022
This is my preview for the current object :
preview: {
    select: {
      title: "title",
      media: "image",
    },
    prepare({ title, media }) {
      return {
        title: title,
        subtitle: "Text and Image",
        media,
      };
    },
  },
Let's say I want to show the portable text if title is not added by the user.
May 30, 2022, 12:42 PM
I believe we automatically parse it to plain text when you don’t use the
prepare
function. The function behind the link will work. You can also
import { toPlainText } from '@portabletext/react'
…which is pretty much the same function, but maintained by us
May 30, 2022, 1:25 PM
Maybe we should mention it in the documentation then. 🙂 Might be better than people copying and pasting that function if they already use the React adapter.
May 30, 2022, 1:27 PM
or even better, we should include/expose the function that’s already in the studio 🙂
May 30, 2022, 1:28 PM
{
    name: "content",
    type: "array",
    title: "Article sections",
    of: [
      {
        name: "textBlock",
        type: "object",
        title: "Text block",
        fields: [
          {
            name: "portableText",
            title: "Portable Text",
            type: "portableText",
          },
        ],
      },
      {
        type: "textAndImage",
      },
      {
        type: "heroTextBlockAndImage",
      },
      {
        type: "textAndImageCTA",
      },
    ],
  },
May 30, 2022, 1:31 PM
This is inside my article.js document ☝️
May 30, 2022, 1:31 PM
Ah. Then you need to select the
content
field, and find the first
textBlock
and run its
portableText
array through the plaintext function inside
prepare
May 30, 2022, 1:36 PM
A quicker version is to select the first
textBlock
and the first paragraph in said
portableText
and take the text from there. It will probably work fine most of the time.
content
 .find(({_type}) => _type === "textBlock")
 ?.portableText
 ?.find(({_type}) => _type === "block")
 ?.children[0]
  .text

May 30, 2022, 1:42 PM
Feeling kinda stuping 😅
May 30, 2022, 2:08 PM
preview: {
            select: {
              title: "portableText",
            },
            prepare({ content }) {
              return {
                title: content
                  .find(({ _type }) => _type === "textBlock")
                  ?.portableText?.find(({ _type }) => _type === "block")
                  ?.children[0].text,
              };
            },
          },
May 30, 2022, 2:08 PM
You need to select that property.
May 30, 2022, 2:09 PM
You need to select that property. Right now,
preview.prepare()
only receives
title
because that’s what you defined in
preview.select
. If you want the property to be called
content
, you need to update
title: "portableText"
to
content: "portableText"
.
May 30, 2022, 2:09 PM
This is the error I get in the console
May 30, 2022, 2:13 PM
When using the code above ☝️
May 30, 2022, 2:13 PM
This got it working: 🙂
preview: {
            select: {
              title: "portableText",
            },
            prepare({ title }) {
              return {
                title: title[0].children[0].text,
              };
            },
          },
May 30, 2022, 2:18 PM
thanks
user F
!! 🙏
May 30, 2022, 2:18 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?