Reusing default Blockquote component for custom PortableText style

3 replies
Last updated: Aug 27, 2020
I want to support pull-quotes in a PortableText field, and the default rendering for a blockquote is sufficient for me, so I am doing the following. Is this the best way to go about this? I wasn’t able to find any documentation on reusing these default component styles.
import Blockquote from "@sanity/form-builder/lib/inputs/PortableText/Text/Blockquote"

// in a `block` type's `styles` array:
{
  title: "Pull Quote",
  value: "pullquote",
  blockEditor: {
    render: Blockquote,
  },
}
AI Update

I understand you're trying to reuse the default blockquote rendering for a custom "pullquote" style in Portable Text. Your approach of importing from @sanity/form-builder is not the recommended way, and this pattern has actually changed significantly in recent Sanity Studio versions.

The Issue with Your Approach

Importing internal components like Blockquote from @sanity/form-builder/lib/inputs/PortableText/Text/Blockquote is:

  1. Accessing private/internal APIs that aren't meant to be public
  2. Not documented or supported officially
  3. Likely to break between Studio versions since these internal paths can change

The blockEditor.render property you're using was actually deprecated in Sanity Studio v3.1+. According to the migration documentation, the modern approach uses a component property instead.

The Modern Approach (Studio v3+)

Instead of trying to reuse the default blockquote component, you should configure your schema like this:

{
  type: 'block',
  styles: [
    {title: 'Normal', value: 'normal'},
    {title: 'Pull Quote', value: 'pullquote'},
    // other styles...
  ]
}

Then handle the rendering on the frontend when you display the Portable Text content. If you want pullquotes to look like blockquotes, simply map them in your serializer:

import {PortableText} from '@portabletext/react'

const components = {
  block: {
    pullquote: ({children}) => <blockquote>{children}</blockquote>,
  }
}

<PortableText value={content} components={components} />

If You Need Custom Studio Rendering

If you specifically want to customize how the pullquote appears in the Studio editor (not just the frontend), the modern way is described in the Customize the Portable Text Editor documentation. You'd use the component property instead of blockEditor.render:

{
  title: 'Pull Quote',
  value: 'pullquote',
  component: MyCustomPullquoteComponent, // Your own component
}

Bottom line: There isn't an officially supported way to directly reuse Sanity's internal default components. The separation between schema configuration (what styles exist) and rendering (how they appear) is intentional. Configure your styles in the schema, then handle the visual presentation in your serializers/components where you have full control.

Show original thread
3 replies
The built-in way would be in the
styles
array add
{title: 'Pull Quote', value: 'blockquote'}

blockquote
is a default style type so should need any custom objects to make it happen
Our default portable text styles aren’t super prominently displayed in the docs, but here’s the full list:
https://www.sanity.io/docs/configuration#configuring-styles-for-text-blocks-8997d6860827
The built-in way would be in the
styles
array add
{title: 'Pull Quote', value: 'blockquote'}

blockquote
is a default style type so should need any custom objects to make it happen
Our default portable text styles aren’t super prominently displayed in the docs, but here’s the full list:
https://www.sanity.io/docs/configuration#configuring-styles-for-text-blocks-8997d6860827
oh, i misunderstood! Yeah, what you’re doing should totally work, but I’m not sure it would be a “best practice” across the board (probably why it’s not documented, though i’m not sure about that).
If you’re only rendering one style or decorator using that style, I don’t think it’s a UX problem, but if you had both blockquote and a new decorator using the blockquote rendering in the editor, it might be confusing.

I think in your usecase, it’s probably not a big deal to do it this way. Most of the time, you’d probably want to render a custom component to differentiate for editors

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?