Adding custom preview to image document type in Sanity.io

11 replies
Last updated: May 10, 2021
I'm adding a custom preview to an
image
based document type. This seems to be possible, however, I cannot seem to get the
media
element working, since it would have reference itself. I've tried the following:
preview: {
  select: {
    originalFilename: 'asset.originalFilename',
    filename: 'filename',
    name: 'i18n.en.name',
    media: '@', // this would need to work somehow
  },
  prepare: ({ originalFilename, filename, name, media }) => {
    const title = filename ?? originalFilename;
    return { title, subtitle: name, media };
  },
}
May 10, 2021, 3:47 PM
Is this preview on the document or an object? Since any image input field will need to be a field, I’m trying to visualize why it can’t be targeted.
May 10, 2021, 4:10 PM
Hi
user A
- it's a document 'inheriting' from the base
image
document type:
export default {
  name: 'page.image',
  title: 'Image',
  type: 'image',
  validation: (Rule) =>
    Rule.custom((value) => {
      return value?.asset?._ref ? true : 'Missing asset';
    }),
  options: {
    hotspot: true,
  },
  fields: [
    {
      name: 'filename',
      title: 'Filename',
      type: 'filename',
    },
  ],
  preview: {
    select: {
      originalFilename: 'asset.originalFilename',
      filename: 'filename',
      media: '@'
    },
    prepare: ({ originalFilename, filename, media }) => {
      const title = filename ?? originalFilename;
      return { title, subtitle: label, media };
    },
  },
};
May 10, 2021, 4:12 PM
Which is then used inside a
page
document like so:
{
  name: 'images',
  title: 'Images',
  type: 'array',
  of: [
    {
      type: 'page.image',
    },
  ],
  options: {
    editModal: 'fullscreen',
  },
},
May 10, 2021, 4:14 PM
I think it would be useful for image based documents to fallback to the default
media
(the image thumbnail) when
media
has not been returned explicitly from the
prepare
(or
select
) options. Currently, if I leave out
media
(which is
undefined
anyway in the example above) it will preview as a generic 'document' icon.
May 10, 2021, 4:16 PM
You were able to name your image object with a period?
May 10, 2021, 4:22 PM
Oh, sure - AFAIK you can definitely name your document types with a period in them. It's a pattern I adopted (and I think I've seen examples of other projects doing this, too)
May 10, 2021, 4:24 PM
I guess I was misinterpreting these guidelines . You’re right, though—Sanity even does it with
sanity.imageAsset
.
May 10, 2021, 4:28 PM
Indeed, and so does https://www.sanity.io/plugins/sanity-plugin-media for
media.tag
(I think this is where I first noticed this outside of Sanity internals).
May 10, 2021, 4:29 PM
Just as you’re getting
asset.originalFilename
, I’d expect you could get
asset._id
and use that as your
media
preview. Something like:

preview: {
  select: {
    id: 'asset._id',
    originalFilename: 'asset.originalFilename',
    filename: 'filename',
  },
  prepare: ({ id, originalFilename, filename }) => {
    const title = filename ?? originalFilename;
    return {
      title,
      media: id && {asset: {_ref: id}};
    },
  },
}
I hope that works!
🤞 (Edit: Added short circuit conditional to
media
).
May 10, 2021, 6:53 PM
Cool, that worked, thanks! I did not expect that
media
would take a raw
_ref
like that - I somehow figured it would have been dereferenced by the point it came into
prepare
.
May 10, 2021, 7:01 PM
I looked at what the studio does itself and hoped it would work for you, too.
May 10, 2021, 7:05 PM

Sanity– build remarkable experiences at scale

The Sanity Composable Content Cloud is the 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?