How to preview content on an object with an array of media in Sanity.io

9 replies
Last updated: Jul 30, 2022
Hey folks, how would I preview content on an object that has an array of media? Ideally I’d like to show an icon depending on whether is media is a video or an image.
AI Update

You can show different icons for images vs videos in your preview by using the prepare function to conditionally return an icon based on the media type. Here's how to approach it:

import { ImageIcon, PlayIcon } from "@sanity/icons";

export const mediaObjectType = defineType({
  name: 'mediaObject',
  type: 'object',
  fields: [
    {
      name: 'mediaItems',
      type: 'array',
      of: [
        { type: 'image' },
        { type: 'file' } // for videos
      ]
    }
  ],
  preview: {
    select: {
      // Get the first media item from the array
      firstMedia: 'mediaItems.0',
      // You can also select the asset type directly if structured differently
      mediaType: 'mediaItems.0._type'
    },
    prepare({ firstMedia, mediaType }) {
      // Determine if it's a video or image
      const isVideo = firstMedia?.asset?.mimeType?.startsWith('video/');
      
      return {
        title: 'Media Object',
        subtitle: isVideo ? 'Video content' : 'Image content',
        media: isVideo ? PlayIcon : (firstMedia ?? ImageIcon)
      };
    }
  }
});

For individual array items, you can configure previews on each media type:

{
  name: 'mediaItems',
  type: 'array',
  of: [
    {
      type: 'image',
      preview: {
        select: {
          media: 'asset'
        },
        prepare({ media }) {
          return {
            title: 'Image',
            media: media ?? ImageIcon
          };
        }
      }
    },
    {
      type: 'file',
      preview: {
        select: {
          fileName: 'asset.originalFilename',
          mimeType: 'asset.mimeType'
        },
        prepare({ fileName, mimeType }) {
          const isVideo = mimeType?.startsWith('video/');
          return {
            title: fileName || 'File',
            subtitle: isVideo ? 'Video' : 'File',
            media: isVideo ? PlayIcon : DocumentIcon
          };
        }
      }
    }
  ]
}

The key points from Sanity's preview configuration:

  1. Use numeric indices to access array items in select (e.g., mediaItems.0 for the first item)
  2. The prepare function lets you conditionally return different icons based on the content
  3. Always provide a fallback icon using the ?? operator when media might not be available
  4. You can check the mimeType property on assets to distinguish between images and videos

This approach works for both the parent object preview and individual array item previews, giving you flexibility depending on where you need the icons to appear in Studio.

The object within my document array:
The media array in the object
Hey
user A
! You can create a custom preview . In your
prepare
function, you'll want to conditionally render your icon. If you share your schema and the fields you're checking against I can be more specific.
Thanks
user M
, here’s the schema for the object:

export default {
  title: "Media Section",
  name: "mediaSection",
  type: "object",
  fields: [
    {
      title: "Media",
      name: "media",
      type: "array",
      of: [{ type: "img" }, { type: "video" }],
      validation: (Rule) => Rule.max(3),
    },
  ],
  preview: {
    select: {
      title: "media.0.alt",
      media: "media.0",
      mediaType: "media.0._type",
    },
    prepare({ title, media, mediaType }) {
      return {
        title: title,
        media: media,
        icon: mediaType == "image" ? FiImage : FiFilm,
      };
    },
  },
};
Hello
user A
another question (I am trying to replicate your question):Would you like the preview to be only the icon or would you like to have an additional icon next to a preview of the uploaded `img`/`video`?
There are different ways to do so, and the schema you shared is about both as far as I can see…

You can specify an icon in the `img`/`video` schemas, which will then be displayed in the options in
+ Add Item
(see pic) or add an icon in the preview of the array in the Media section.
Hi
user J
, I would like only one thing to show. Ideally, if it’s an image, we preview the image. And if it’s a video, then show the icon (I’m using vimeo so I don’t think we can preview the asset directly?)
The icons show up in the “Media section” array as intended, but I would like to show the preview in the the parent component aka the “Project contents” array as well so that it’s easy to know what’s in each “Media section”
ah! So can you add this schema as well? 🙂
Looks like I ended up figuring this out! Thanks for all the help 🙏

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?