Getting the original image ratio without adding it to the GROQ query in Sanity.io

14 replies
Last updated: Mar 30, 2021
Hi guys, i was wondering if there is a way to get the original image ratio without adding it to the GROQ query. I’d like to know the ratio of the image without restricting the content managers too much by fixing them in the schema. We’ve used the GROQ way before, like this:
const query = `*[_type == "solutions-singleton"] {
  ...,
  "platformsImage": fields.platforms.platformsImage.asset->{
    url,
    metadata {
      dimensions
    }	
  },
}`
but this doesn’t seem very scalable. Is there a way to get the ratio of the image by using, for example, the
@sanity/image-url
helper?
AI Update

Good news! You don't need to query for dimensions in GROQ every time. The image asset _id actually contains the dimensions encoded in its format, and @sanity/image-url already parses this information internally.

The asset _id follows this pattern:

image-<sha1hash>-<width>x<height>.<extension>

So you can extract the dimensions directly from the asset reference without expanding it in your GROQ query. Here's how:

// Your GROQ query can just be:
const query = `*[_type == "solutions-singleton"] {
  ...,
}`

// Then in your code:
function getImageDimensions(imageAsset) {
  // imageAsset._ref will be something like:
  // "image-abc123-1920x1080-jpg"
  const dimensions = imageAsset._ref.split('-')[2];
  const [width, height] = dimensions.split('x').map(Number);
  const aspectRatio = width / height;
  
  return { width, height, aspectRatio };
}

Even better, if you're already using @sanity/image-url, it parses these dimensions internally through its parseAssetId function. While it doesn't expose a direct method to retrieve the ratio, you could:

  1. Extract it yourself from the asset reference as shown above
  2. Open a feature request (or PR) on the @sanity/image-url GitHub repo to expose dimension information - the maintainers suggested this would be a welcome addition

This approach is much more scalable than projecting metadata in GROQ since:

  • You don't need to customize your query for each image field
  • Your TypeScript types remain consistent with your generated schema
  • No additional data fetching required
  • Works with any number of images on a page

The dimensions are already there in the asset ID - you just need to parse them!

Hi Jorrit, not sure if there’s any other way to get the image ratio… but why is the GROQ approach not scalable? If it’s just the syntax, you can turn it into a reusable string and use it whenever you need to query for images.
Well, say I have a page with 10+ images of which I’d like to know the ratio. I’ll have to specify each image into the GROQ query, right?
Doesn’t work very well with Typescript as well, since the response is different from the
SolutionsSingleton
type generated by
sanity-codegen
So the response would be something like:

type Response = SolutionsSingleton & {
  platformsImage: {
    url: string
    metadata: {
      dimensions: string
    }
  }
}
So you’d have to customize the typed response for every page. It can work, just doesn’t seem really ideal to me
yeah I feel you, my approach is not too different than yours. I put the common fragments into a string &amp; a type, i.e
const imageFragment = ({ fields }) => `${fields}.asset -> { alt, url, etc }`

export type ImageResult = { alt: string, url: string, etc: ... }
And just include them where I needed. Not ideal ideal, but it’s not too painful either. Until we get a codegen that can generate types per query, I think this is as good as it gets
Thanks for the snippet, I’ll check 👍
The
_id
of the asset document that the image field has a reference to is on the format
image-<sha1hash>-<width>x<height>.<extension>
so you should be able to get the aspect ratio by just looking at it
🙂
Wow, that's a neat trick!
Yeah 🙂 we use this in
@sanity/image-url
, btw, so if you use that one you should be good already
Woa, that’s nice, thanks!
There is no out-of-the-box option included in
@sanity/image-url
to retrieve the ratio of the image though right? Would be a really handy feature!
yeah, you're right. Looks like it just uses it internally but doesn't expose it. Feel free to open an issue (or even better, a PR) for it in the github repo 🙂
Will have a look at it, thanks 🖐️

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?