I've noticed I can add a preview to an image type but it only pulls data from the settings field name in the fields[] within it.

14 replies
Last updated: Jan 27, 2021
Sorry, got another question! I've noticed I can add a
preview
to an image type but it only pulls data from the
settings
field name I have created in the
fields[]
within it. This wasn't clear that it is possible in the docs (https://www.sanity.io/docs/image-type ). Can I reference the
image
asset in this preview as it doesn't seem to work?
        {
          title: 'Image',
          name: 'image',
          type: 'image',
          options: { hotspot: true },
          fields: [
            {
              title: 'Settings',
              name: 'settings',
              type: 'portfolioGallerySettings',
              options: { isHighlighted: true },
            },
          ],
          preview: {
            select: {
              size: 'settings.size',
              artist: 'settings.artistCredit.title',
              caseStudy: 'settings.caseStudy.content.title',
              media: 'image' // <<< This doesn't work. Can I get the parent image asset somehow?
            },
            prepare({ size, artist, caseStudy, media }) {
              return {
                title: 'derp'
              }
            },
          },
AI Update

Good news - yes, you can reference the parent image asset in your preview! The issue is that when you're working with an image type, the actual asset reference is stored in a nested asset property, not directly on image.

Based on the preview configuration documentation, you need to use dot notation to access the asset. Try this:

preview: {
  select: {
    size: 'settings.size',
    artist: 'settings.artistCredit.title',
    caseStudy: 'settings.caseStudy.content.title',
    media: 'asset' // Reference the asset directly
  },
  prepare({ size, artist, caseStudy, media }) {
    return {
      title: caseStudy || artist || 'Image',
      subtitle: size,
      media: media
    }
  },
}

The key is using 'asset' instead of 'image' in your select. When you're defining a preview within an image type definition, you're already in the context of that image object, so you can reference asset directly.

If you need to access other properties of the image object (like hotspot or crop data), you can also select those:

select: {
  size: 'settings.size',
  artist: 'settings.artistCredit.title',
  media: 'asset',
  hotspot: 'hotspot',
  crop: 'crop'
}

The preview system lets you access nested fields using dot notation, and you can even access items in arrays using numeric indices (like 'images.0.asset' for the first image in an array). This works for both regular fields and referenced documents.

I'm not on a computer to check, but try
media: 'image.asset'
.
Hi Geoff! Shows up as
undefined
if I try
image
,
image.asset
etc. Doesn't show that
preview
is even a property of image in the docs so not sure how
settings
is coming though but not the parent type
image
I will get on a computer and check.
Awesome! Just to point out, I have to use an
image
in an
array
and not an
object
(containing an image and settings) as sanity has a weird way of handling bulk uploading assets into the array.
Okay. I’m assuming that’s all one contiguous block of code above. As it’s written, it seems odd that the image doesn’t just display automatically.
Ohh… hang on. I re-looked at your code.
Try
image: 'image.asset'
in preview.select and then
media: image
in prepare.
No joy i'm afraid. I'm also logging out the result in prepare with no joy. Perhaps this is a bug or not implemented? Here is what the above code is nested in:

export default {
  title: 'Gallery',
  name: 'portfolioGallery',
  type: 'object',
  fields: [
    {
      name: 'items',
      type: 'array',
      of: [
        IMAGE OBJECT HERE...
Do you want the preview to apply to the item in your array or to the greater document?
This will be for the item in the array. Should look like this but with the preview image:
Okay. I’m trying to visualize your entire schema, but I have something that I think is almost identical and it works like what you’re after.
It might be that I’m doing an object inside the array and you’re not, but here’s what I am using (with a bunch of irrelevant stuff cut out):


{
      type: 'array',
      name: 'minister',
      title: 'Minister',
      of: [{
        type: 'object',
        fields: [
          {
            name: 'member',
            title: 'Member',
            type: 'reference',
            to: [{ type: 'mla' }],
          },
        ],
        preview: {
          select: {
            image: 'member.image.asset',
          },
          prepare({ image }) {
            return {
              media: image,
            };
          },
        },
      }],
    },

Hi Geoff, appreciate your help with this. This does indeed work however in my particular use case I cannot use an
object
type inside an
array
. The reason being that the user needs to be able to drag a load of images/videos into the array and that doesn't seem to work unless the
image
and
file
types are loose and not nested in something like a object 😔
The page you took a screenshot of—if you go to inspect, can you post the JSON for the array?
Doing that helped reveal that all I need to use was 'asset'! Turns it is was something so simple...just presumed you would need to reference the field name
image
😛 Thanks a lot for this Geoff.
Nice! Good to hear. 🙂

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?