Custom preview for file type in array: missing props.media object

8 replies
Last updated: Mar 14, 2023
Hi. I'm currently making a custom
component.preview
for an array item. For an
image
type in the array I get the props data I need passed down, specifically the props.media object. For the
file
type I don't get any useful info apart from the title and the props.media object is undefined. Is this a bug or is there another way to get the
file
info so I can style a custom preview? It also doesn't return the array key of the item.
AI Update

Based on the documentation I've reviewed, what you're experiencing is actually the expected behavior - preview configuration works the same way for all types in Sanity, including both image and file types. There isn't automatic prop resolution that works differently between them.

How Preview Configuration Works

According to the preview configuration documentation, you need to explicitly use preview.select to specify which fields should be available in your preview - this applies to images, files, and all other types equally. The standard pattern looks like this:

{
  name: 'myFile',
  type: 'file',
  preview: {
    select: {
      title: 'asset.originalFilename',
      subtitle: 'asset.mimeType',
      media: 'asset'  // Explicitly select the asset
    }
  }
}

Accessing the _key Property

The _key is an internal property that Sanity uses to track array items. If you need access to it in your preview, you must explicitly select it:

preview: {
  select: {
    title: 'asset.originalFilename',
    media: 'asset',
    key: '_key'  // Explicitly select _key
  }
}

Using Custom Preview Components

If you're creating a custom preview component using the Form Components API, you define it like this:

{
  name: 'myFile',
  type: 'file',
  components: {
    preview: MyCustomPreviewComponent
  },
  preview: {
    select: {
      title: 'asset.originalFilename',
      media: 'asset',
      _key: '_key'
    }
  }
}

Important note: Custom preview components (defined via components.preview) only work in certain contexts, primarily inside the document pane. They may not work in all list views or reference selectors.

Why Files and Images Seem Different

The reason you might perceive different behavior between image and file types is that images have built-in visual thumbnail rendering in Studio, while files don't have a default visual representation. However, both require the same preview.select configuration pattern to make data available to your preview.

For files, you can use icons instead of thumbnails:

import { DocumentIcon } from '@sanity/icons'

preview: {
  select: {
    title: 'asset.originalFilename',
    mimeType: 'asset.mimeType'
  },
  prepare({ title, mimeType }) {
    return {
      title: title || 'Untitled',
      subtitle: mimeType,
      media: DocumentIcon  // Use an icon as the media
    }
  }
}

This isn't a bug - it's the standard way preview configuration works for all types in Sanity. You need to explicitly select the fields you want to use in your preview through the preview.select configuration, regardless of whether you're working with images, files, or any other type.

Show original thread
8 replies
Can you share your code?
Hey
user S
. So it's the props inside the preview component of
video
that is not providing the info like
image
does.

export default defineField({
  name: 'bookGallery',
  title: 'Gallery',
  type: 'array',
  options: {
    layout: 'grid'
  },
  of: [
    defineArrayMember({
      name: 'image',
      title: 'Image',
      type: 'image',
      options: {
        hotspot: true
      },
      components: {
        preview: BookGalleryImagePreview
      }
    }),
    defineArrayMember({
      name: 'video',
      title: 'Video',
      type: 'file',
      components: {
        preview: BookGalleryVideoPreview
      },
    })
  ]
})
Would you find it useful for me to provide a simple 'BookGalleryVideoPreview' example?
No, that’s ok, thankss! I can put together a minimal example for you after I get out of my morning meetings.
Thanks a lot for looking at this!
Ok, you can grab details from your file’s asset using a
preview.select
. Below is an example of grabbing the entire asset or just a single field:
{
          name: 'video',
          title: 'Video',
          type: 'file',
          preview: {
            select: {
              media: 'asset',
              title: 'asset.originalFilename',
              url: 'asset.url'
            },
          },
          components: {
            preview: (props) => {
              console.log(props.title, props.media, props.url);
              return props.renderDefault(props);
            },
          },
        },
Nice. Thanks for this!
You’re welcome!

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?