How to preserve image filename when using fields in Sanity query?

10 replies
Last updated: Sep 5, 2022
When using
image
with
fields
the filename gets removed and says "Untitled". Without the
fields
the filename is shown. How can I bring it back when using
fields
?
AI Update

When you add custom fields to an image type in Sanity, the Studio stops displaying the default filename and shows "Untitled" instead. This happens because adding fields changes how the preview is configured. The solution is to add a preview configuration to your image type that explicitly selects the filename.

The key is to place the preview configuration on the image object itself, not on the array that contains it. Here's how to fix it:

{
  name: 'assetFiles',
  type: 'array',
  title: 'Files',
  of: [
    {
      type: 'image',
      fields: [
        {
          name: 'caption',
          type: 'string',
          title: 'Caption',
        },
        {
          name: 'alt',
          type: 'string',
          title: 'Alt Text',
        }
      ],
      preview: {
        select: {
          title: 'asset.originalFilename',
          media: 'asset'
        }
      }
    }
  ]
}

The important parts here are:

  1. title: 'asset.originalFilename' - This tells Sanity to use the original filename from the asset as the title in the preview
  2. media: 'asset' - This ensures the image thumbnail still displays alongside the filename
  3. Location matters - The preview block must be inside the image object definition (after the fields array), not on the parent array

The asset.originalFilename property is automatically set by Sanity when you upload an image, so you don't need to create any additional fields. Other useful asset properties you could use include asset.url or any other metadata fields available on the asset.

If you want to get fancy, you can also use the prepare function to customize the display further:

preview: {
  select: {
    title: 'asset.originalFilename',
    media: 'asset',
    caption: 'caption'
  },
  prepare({title, media, caption}) {
    return {
      title: title || 'Untitled',
      subtitle: caption,
      media: media
    }
  }
}

This approach gives you back the filename display while maintaining your custom fields for captions, alt text, or any other metadata you need to store with your images.

Show original thread
10 replies
It sounds like you’ll want to set up a preview to tell the Studio what should be your title.
I see! But I would need to first declare something like a title field for this, right? Or is there a way to use the OG filename (standard behaviour)? Without any additional fields it does work.
You won't need to set a
title
field, but you need to select the field you want as a title in your
preview
. Something like this should be sufficient (setting the right-side to the field you want):

preview: {
  select: {
    title: ‘asset.url’
  }
}
That only works if I have a field to set it to! I want it to revert to the default behaviour and use the image filename
I’m curious if you tried this, as the properties on
asset
are read-only and automatically set (i.e., you don’t need to do anything). That said, I was looking for
asset.originalFilename
rather than
asset.url
.
With no fields, I get `A`:

{
	name: 'myArray',
	title: 'My Array',
	type: 'array',
	of: [
		{
			name: 'myImage',
			type: 'image',
		},
	],
}
Setting an
alt
field, I get `B`:

{
	name: 'myArray',
	title: 'My Array',
	type: 'array',
	of: [
		{
			name: 'myImage',
			type: 'image',
			fields: [
				{
					name: 'alt',
					title: 'Alt Text',
					type: 'string',
				}
			],
		},
	],
}
Adding a preview, I get `C`:


{
	name: 'myArray',
	title: 'My Array',
	type: 'array',
	of: [
		{
			name: 'myImage',
			type: 'image',
			fields: [
				{
					name: 'alt',
					title: 'Alt Text',
					type: 'string',
				}
			],
			preview: {
				select: {
					title: 'asset.originalFilename'
				},
			}
		},
	],
}
I can see that the image is no longer previewed in the list, so I suspect you’ll need to specify a prepare function in your preview and add a
media
property. That’ll be a valid need, but is additional to the original question.
For context, the original suggestion (using
asset.url
) returns the url to the image (e.g.,
<https://cdn.sanity.io/images/PROJECT_ID/DATASET/fileNameHash>…
).
Hey
user A
, thank you for the continuous support and this long answer!
This is how my image field is structured:

{

name: "assetFiles",

type: "array",

title: "Files",

of: [

{

type: "image",

options: {

isHighlighted: true,

},

fields: [

{

name: "caption",

type: "string",

title: "Bildunterschrift",

options: {

isHighlighted: true,

},

},

{

name: "fullscreen",

type: "boolean",

title: "Vollformat",

initialValue: false,

options: {

layout: "checkbox",

isHighlighted: true,

},

},

],

},

],

fieldset: "assets",

preview: {

select: {

title: "asset.originalFilename",

},

},

},
Hey
user A
, thank you for the continuous support and this long answer!
This is how my image field is structured:

{

name: "assetFiles",

type: "array",

title: "Files",

of: [

{

type: "image",

fields: [

{

name: "caption",

type: "string",

title: "Bildunterschrift",

options: {

isHighlighted: true,

},

},

{

name: "fullscreen",

type: "boolean",

title: "Vollformat",

initialValue: false,

options: {

layout: "checkbox",

isHighlighted: true,

},

},

],

},

],

fieldset: "assets",

preview: {

select: {

title: "asset.originalFilename",

},

},

},

As you can see, I implemented your code from
C
.
I then uploaded a fresh image, which automatically results in
Untitled
(and, as you said, no image preview). If I put some text in the caption field, the captions is shown as Image title, but never the image filename.
I’m super sorry if there is some mistake in my code or my understanding of your reply!
No problem, Max! It looks like your preview is on the array. Could you please try putting it on the image (i.e., right after the fields array you set on your image)?
user A
Ahhhh! Yes, this works!! TYSM ❤️

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?