How to change the preview for a grid tile in a schema with an array of objects.

12 replies
Last updated: Jun 4, 2021
hello, my schema contains an array of objects. i'm display the array with
options.layout: 'grid'
, but the grid doesn't seem to display the video field from my object that i'd like, it appears like attached. does anybody know how i'm able to change the preview for this grid tile/what fields to return from the preview function if any?
AI Update

Based on the documentation about preview configuration, when you're using options.layout: 'grid' on an array of objects, the grid tiles display based on the preview configuration you define on your object type schema.

For your video field to appear in the grid tile, you need to add a preview configuration to your object type definition. Here's how to set it up:

{
  name: 'yourObjectType',
  type: 'object',
  fields: [
    {
      name: 'video',
      type: 'file', // or 'mux.video' if using Mux
    },
    // your other fields...
  ],
  preview: {
    select: {
      title: 'title', // or whatever field you want as the title
      media: 'video', // this tells Sanity to use the video field for the media preview
    },
    prepare({title, media}) {
      return {
        title: title || 'Untitled',
        media: media, // the video will be used as the thumbnail
      }
    }
  }
}

The key points from the preview configuration documentation:

  1. select object: Specifies which fields to extract - set media: 'video' to pull your video field
  2. prepare function: Transforms the selected data before display - return an object with title, subtitle (optional), and media

If you want to show additional information, you can also add a subtitle:

prepare({title, media, duration}) {
  return {
    title: title || 'Untitled Video',
    subtitle: duration ? `${duration}s` : 'No duration',
    media: media
  }
}

The grid layout will then display your video thumbnail (or a file icon if no thumbnail is available) along with the title and any subtitle you configure. This works for arrays of objects when you set options: { layout: 'grid' } on the array field itself.

You can also provide a fallback icon if the video doesn't have a thumbnail by using the nullish coalescing operator in your prepare function, as shown in this guide on creating richer array item previews.

Hi User. You can use the
preview.select.media
property to specify a field that can be used as a preview thumbnail, as they’ve done below the gotcha here .
thanks so much!
export default [
  {
    name: "playPage",
    type: "document",
    fields: [
      { name: 'title', type: 'string' },
      {
        name: 'videos',
        type: 'array',
        of: [{ type: 'videoWithSize' }],
        options: {
          layout: 'grid',
        },
        preview: {
          select: {
            media: 'videoWithSize.video'
          },
        }
      }
    ]
  },
  {
    name: 'videoWithSize',
    type: 'object',
    // preview: {
    //   select: {
    //     media: 'video',
    //   },
    //   // prepare(selection) {
    //   //   console.log('selection', selection);
    //   //   return ({ media: selection.video })
    //   // },
    // },
    fields: [
      { name: 'size', type: 'string' },
      { name: 'video', type: 'cloudinary.asset' },
    ]
  }
];
any idea why this isn't working?
i've tried it with the preview in the
videoWithSize
object as well, no luck
also it's worth noting that the selected field is a pointing to a video
when i log the selection inside
videoWithSize
i get
selection 
{media: {…}}
media:
access_mode: "public"
bytes: 10601093
created_at: "2021-03-10T23:37:29Z"
duration: 9
format: "mp4"
height: 1080
metadata: []
public_id: "jimmybrings_sophiemonk_16_9_81a37ecc_8cf10b5bf4"
resource_type: "video"
secure_url: "<https://res.cloudinary.com/paper-moose/video/upload/v1615419449/jimmybrings_sophiemonk_16_9_81a37ecc_8cf10b5bf4.mp4>"
tags: []
type: "upload"
url: "<http://res.cloudinary.com/paper-moose/video/upload/v1615419449/jimmybrings_sophiemonk_16_9_81a37ecc_8cf10b5bf4.mp4>"
version: 1615419449
width: 1920
_key: "wgSlAllEOSrVzx4DWr2cG"
_type: "cloudinary.asset"
_version: 1
__proto__: Object
it’s worth noting that the selected field is a pointing to a video
I’ve never seen someone put a video in the preview. You can use JSX in
media
, and when I tried a video element it did incorporate the video (though it wouldn’t autoplay, I could right-click and watch picture-in-picture and when I paused, the preview thumbnail updated to the current frame). I’d have questions about performance though and might suggest pulling a thumbnail from each video instead.
Edit: By adding
controls
to the video element, it’s possible to play the video. 🤷‍♂️

media: <video src="<http://res.cloudinary.com/paper-moose/video/upload/v1615419449/jimmybrings_sophiemonk_16_9_81a37ecc_8cf10b5bf4.mp4>" autoplay controls width="300" height="200">Not supported</video>

hmm ok
so just so i understand correctly, the return value of
prepare
must contain an object with a
media
property which points to an image or video element is that right?
for it to display in the array grid correctly
the return value of 
prepare
 must contain an object with a 
media
 property which points to an image or video element
For an image, I think a url would suffice. The extra steps in prepare are only needed to try and render out a video (same would go if one wanted to render out emojis, like the last code block in this section ).

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?