How to Access the Meta-Data of an Uploaded Image within a Custom Input Component

4 replies
Last updated: Oct 12, 2021
Hi Everyone,
I'm creating a custom input component in Sanity Studio. I need to access the meta-data of the
uploaded image within that custom input component.
As of now I can only see the _ref and the _type properties in the image asset,

Does anyone have an idea how I can extract metadata of the image in custom input component?
AI Update

When you're working with a custom input component and only seeing _ref and _type in your image asset field, you'll need to query the actual asset document to get the metadata. The image field only stores a reference to the asset, not the metadata itself.

Here's how you can access the image metadata in your custom input component:

First, make sure you've configured your image field schema to include the metadata you need. In your schema definition, add the metadata options:

{
  name: 'myImage',
  type: 'image',
  options: {
    metadata: ['exif', 'location', 'palette'] // Add the metadata types you need
  }
}

Note that dimensions, hasAlpha, and isOpaque are always included automatically, while blurhash, lqip, and palette are included by default. You need to explicitly add exif and location if you want those.

In your custom input component, you'll need to use the Sanity client to fetch the full asset document:

import { useClient } from 'sanity'
import { useEffect, useState } from 'react'

export function MyCustomImageInput(props) {
  const client = useClient({apiVersion: '2023-01-01'})
  const [metadata, setMetadata] = useState(null)
  
  useEffect(() => {
    const assetRef = props.value?.asset?._ref
    
    if (assetRef) {
      // Query the asset document to get metadata
      client.fetch(`*[_id == $assetId][0].metadata`, { assetId: assetRef })
        .then(data => setMetadata(data))
    }
  }, [props.value?.asset?._ref])
  
  // Now you can access metadata.dimensions, metadata.palette, etc.
  return (
    <div>
      {props.renderDefault(props)}
      {metadata && (
        <div>
          <p>Dimensions: {metadata.dimensions?.width} x {metadata.dimensions?.height}</p>
          <p>Palette: {JSON.stringify(metadata.palette)}</p>
        </div>
      )}
    </div>
  )
}

There's also a helpful guide on creating a custom input component for metadata that shows how to display and even edit metadata directly at the document level.

Important note: Metadata is processed asynchronously after upload, so it might not be immediately available. Your queries might return empty results right after uploading an image until the processing completes.

The metadata you can access includes:

  • dimensions (width/height) - always included
  • palette (color information) - included by default
  • lqip (low quality image placeholder) - included by default
  • blurhash - included by default
  • exif (camera/photo data) - must be explicitly enabled
  • location (GPS coordinates) - must be explicitly enabled
You need to resolve the reference. Are you using groq? If so, have a read on this page for a good intro to references and how to resolve them: https://www.sanity.io/docs/how-queries-work#db43dfd18d7d
Essentially your query to get the image field would look something like
image->
to grab all the image reference data.
Thanks
user S
šŸ™‚ , But I need to access the meta-data within the Sanity Studio it self to create custom input component . I'm using withDocument HOC to access the fields of the document. I can access other data such as string, object without any issue, but there is an issue in image type.
Oh, sorry, I totally missed that šŸ˜… I haven’t done that so I don’t know if there’s a better way, but you could use groq in the studio as well and resolve the reference. It would be an async job regardless, so there might not be a built in way to do it.

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?