Adding custom preview for inline object with image array in block content

9 replies
Last updated: Jan 27, 2026
Hey, I try to add an array of images to my block-content array like this (not my exact schema but works for demonstration purposes):
{
 name: "blockContent",
 type: "array",
 of: [
  { type: "block" }, 
  { type: "object",
    fields: [{
      name: "gallery",
      type: "array",
      options: {layout: "grid"},
      of: [{type: "image"}]
    }]
  }
 ],
While the data from this schema looks exactly what you would expect, the presentation of the gallery object isn’t particularly pretty.

Any way to change that? Didn’t find a way to add a custom preview component to the editor that is not a block-type.
AI Update

Based on the recipe I found in the Sanity documentation, you can definitely add custom preview components to objects in Portable Text! Here's how to solve your problem:

You need to add a components key with a preview property to your object schema. Here's your example updated:

{
  name: "blockContent",
  type: "array",
  of: [
    { type: "block" }, 
    { 
      type: "object",
      name: "gallery",
      fields: [{
        name: "gallery",
        type: "array",
        options: {layout: "grid"},
        of: [{type: "image"}]
      }],
      preview: {
        select: { 
          images: 'gallery',
        },
      },
      components: {
        preview: ImageGalleryPreview,
      }, 
    }
  ],
}

Then create your custom preview component:

import { Flex, Stack } from '@sanity/ui'
import { urlFor } from './image-url-builder'

export default function ImageGalleryPreview(props) {
  const { images, schemaType } = props
  const schemaTitle = schemaType.title

  const modifiedProps = { 
    ...props, 
    title: schemaTitle,
  }

  return (
    <Stack space={[1]}>
      <>
        {props.renderDefault(modifiedProps)}
      </>
      <Flex 
        style={{ 
          gap: '5px',
          overflowX: 'scroll'
        }}
      >
        {images?.map((image) => (
          <img
            key={image._key}
            src={image.asset ? urlFor(image).url() : ''}
            style={{
              width: '400px',
              height: '200px',
              objectFit: 'cover',
            }}
            alt={image.alt}
          />
        ))}
      </Flex>
    </Stack>
  )
}

You'll also need an image URL builder:

import imageUrlBuilder from '@sanity/image-url'
import { client } from './sanity-client'

const builder = imageUrlBuilder(client)

export function urlFor(source) {
  return builder.image(source)
}

The key is using the preview configuration with select to choose which fields to pass to your component, and then the components.preview property to specify your custom React component. This gives you full control over how your gallery object appears in the Portable Text editor.

You can check out the full custom image gallery preview recipe in the Sanity documentation for more details!

Show original thread
9 replies

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?