Unlock seamless workflows and faster delivery with our latest releases – get the details

Adding a custom preview component to a gallery object in Sanity

9 replies
Last updated: Jun 30, 2022
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.
Jun 28, 2022, 8:48 AM
hey, just solved this one myself in the last week ... let me grab my custom preview component real quick
Jun 28, 2022, 8:51 AM
ok, first here's my gallery component (mostly for reference)

import galleryPreview from '../../previews/GalleryPreview'

export default {
  title: "Image Gallery",
  name: "gallery",
  type: "object",
  preview: {
    select: {
      images: "images",
      columns: "columns"
    },
    component: galleryPreview
  },
  fields: [
    {
      title: "Columns",
      name: "columns",
      type: "number",
      initialValue: 3,
      validation: Rule => Rule.required().min(2).max(5)
    },
    {
      title: "Images",
      name: "images",
      type: "array",
      of: [{type: "imageFull"}],
      options: {
        layout: "grid"
      }
    }
  ]
}
Jun 28, 2022, 8:52 AM
and then my gallery preview component

import React from 'react'
import client from 'part:@sanity/base/client'
import urlBuilder from '@sanity/image-url'

const urlFor = source => urlBuilder(client).image(source)

const galleryPreview = ({ value = {} }) => {

  const cols = value.columns
  let wrapperStyles = {
    display: 'grid',
    gridTemplateColumns:`repeat(${cols}, 1fr)`,
    gap: `10px`,
    lineHeight: 0
  }
  let figureStyles = {
    margin: 0,
    aspectRatio: `1/1`,
  }
  let figureImgStyles = {
    width: `100%`,
    height: `100%`,
    objectFit: `cover`
  }

  return (
    <div style={wrapperStyles}>
      {value &&
        value.images.map(image => (
          <figure key={image._key} style={figureStyles}>
            <img src={urlFor(image).url()} style={figureImgStyles}/>
          </figure>
        ))
      }
    </div>
  )
}

export default galleryPreview
Jun 28, 2022, 8:53 AM
here's what it looks like in my studio
Jun 28, 2022, 8:54 AM
another example ... just to show its using my
columns
field to adjust the display grid
Jun 28, 2022, 8:55 AM
Awesome, that almost works.I can add images and afterwards activate the preview component.

Unfortunately the Desk crashes when I try to add new images with the component active. It tries to resolve the URL for an image with an ID that does not exist in my dataset. I’m a bit confused about this.
Jun 28, 2022, 9:42 AM
ahh, yes, i see that now... i hadn't used the component since i added the preview ... so it was working great for already existing galleries
Jun 28, 2022, 10:31 AM
i had the same error on another preview, and just looked at the gallery ... you'll want to add this

if (!value.images){
    return <span />
  }
I put this just before my return in the preview component
Jun 28, 2022, 10:32 AM
Great, thanks again. Tried to only check for existing values without returning anything instead. That obviously didnt work.
Jun 30, 2022, 10:01 AM

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?