Adding a custom preview component to a gallery object in Sanity
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!
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.