Retrieving image metadata with `getImageAsset` in Sanity and modifying queries to include metadata.

36 replies
Last updated: Mar 31, 2022
I’m trying to retrieve Image metadata with
getImageAsset
of
"@sanity/asset-utils"
but only getting metadata.dimensions. Shouldn’t I get default ones like blurHash too?
AI Update

Based on the information I found, getImageAsset from @sanity/asset-utils only returns basic metadata that's always included by Sanity, which is why you're only seeing dimensions. The blurHash, lqip, and palette fields are not automatically returned by this utility function, even though they're generated by default when you upload images.

Here's what's happening:

The Difference Between Schema Options and Querying

The schema metadata options (like metadata: ['blurhash', 'lqip', 'palette']) control what gets generated during upload, but they don't automatically appear when you use getImageAsset. This utility function only extracts what's embedded in the asset reference itself.

What getImageAsset Returns

The @sanity/asset-utils package's getImageAsset function only provides:

  • dimensions (width/height)
  • hasAlpha
  • isOpaque
  • Basic asset information (format, ID)

These are the fields that are always included and cannot be disabled.

How to Get blurHash and Other Metadata

To access blurHash, lqip, palette, and other metadata, you need to explicitly query for it using GROQ. You can't get it from @sanity/asset-utils alone. Here's how:

// In your GROQ query
*[_type == "yourDocType"] {
  image {
    ...,
    asset-> {
      _id,
      url,
      metadata {
        dimensions,
        blurHash,
        lqip,
        palette
      }
    }
  }
}

For nested or complex structures (like a page builder), you'd use:

*[_type == "caseStudy"] {
  pageBuilder[] {
    ...,
    media_item[] {
      ...,
      image {
        ...,
        asset->
      }
    }
  }
}

The asset-> syntax fetches the complete asset document, including all its metadata.

Why This Matters

The confusion comes from the fact that Sanity generates blurHash, lqip, and palette by default, but these live in the asset document's metadata, not in the image reference itself. The @sanity/asset-utils package works with the reference string (like image-abc123-1920x1080-jpg), which only contains dimensions, format, and asset ID—not the full metadata.

So you'll need to update your queries to include asset-> or asset->metadata wherever you need that additional metadata for your React image component. As shown in this community answer, you'll want to modify all your queries to explicitly request the metadata you need.

Hi
user U
, thank you for the answer. The thing is, I’m trying to do a React image component where I can use the blurhash as a placeholder, and that way I would need to modify all the queries I’m doing, and some of them are pretty complex (dynamic page builder with multiple nested levels
Oh, at a glance, I thought you were somehow getting
dimensions
from the metadata.
Oh, at a glance, I thought you were somehow getting
dimensions
from the metadata.
and I am
although, I’m not defining metadata in any of my queries
thats whats strange
by Sanity docs, blurhash should be included

  {
      name: 'metaImage',
      title: 'Image with metadata',
      type: 'image',
      options: {
        metadata: [
          'blurHash',   // Default: included
          'lqip',       // Default: included
          'palette',    // Default: included
          'exif',       // Default: not included
          'location',   // Default: not included
        ],
      },
    },
Are you not getting a blurHash value back when you query your images?
*[_type == "sanity.imageAsset"
 ][0]{
   _id,
   metadata{
   blurHash
 }
 }

The schema metadata options are booleans in an array while the asset document details are nested objects, which can be confusing.
so I would need to edit all the site queries to include image metadata, is that right?
const query = groq`*[_type == "caseStudy" && slug.current == $slug]{
    "currentPost": {
      ...
    },
    "previousPost": *[_type == "caseStudy" && ^._createdAt > _createdAt]|order(_createdAt desc)[0]{...,"slug": slug.current},
    "nextPost": *[_type == "caseStudy" && ^._createdAt < _createdAt]|order(_createdAt asc)[0]{...,"slug": slug.current}
  }|order(_createdAt)[0]`;
so I’m querying a current, next and previous post on a Blog page, how would I fetch all the images metadata on that query?
Hard to say without seeing the output, but something like:

*[_type == "caseStudy" && slug.current == $slug]{
    "currentPost": {
      ...,
      'metadata': image.asset->metadata
    },
    // ...
If it’s an array of images, you’ll adapt the above accordingly.
Hard to say without seeing the output, but something like:

*[_type == "caseStudy" && slug.current == $slug]{
    "currentPost": {
      ...,
      'metadata': image.asset->metadata
    },
    // ...
so perhaps thats the case
I’m just getting confused with GROQ
because I have this complexed page builder with multiple nested fields
and I just can’t wrap my head around it
anyway thanks!
Can you post an example of what you’re getting back from that query for
currentPost
?
sure
so that
media_item
is what I’m interested in, which returns me an image without any metadata
{
  _key: '9835cbe756b9',
  _type: 'column',
  col_span: 'full_width',
  image: {
    _type: 'image',
    asset: {
      _ref: 'image-715114d0636182e8e7de8ed97dff23ceb911f31d-2760x1550-jpg',
      _type: 'reference'
    }
  },
  mediaType: 'image',
  positioning: 'left',
  videoType: 'embedded'
}
Will it always be images in
media_item
, or are there other types too?
image/video/text
Okay. Later you can add conditionals to only ask for metadata if the item is an image, but for now it’s fine (you’ll just get nulls on non-images). Could you try this?

*[_type == "caseStudy" && slug.current == $slug]{
    "currentPost": {
      ...,
      'metadata': pageBuilder[].media_item[].image.asset->metadata
    },
    // ...
This will not work on
v1
of the API , so you’ll want to use
v2021-03-25
or later.
got them
how would I associate them with the actually assets though?
You’ll want to ask for more than just metadata (e.g.,
_id
).
So maybe this is better:

*[_type == "caseStudy" && slug.current == $slug]{
    "currentPost": {
      ...,
      pageBuilder[]{
        ...,
        media_item[]{
          ...,
          image{
            ...,
            asset->
          }
        }
      }
    },
    // ...
that will do
thank you both

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?