How to Fetch All Images References in a GROQ Request

11 replies
Last updated: May 5, 2021
Is there be a way to fetch all images references in a GROQ request without specifying every single field?As I need the
asset
part of the field mostly, that'd be great šŸ˜„ (url, dimensions, fields linked to it, etc)
*[_id == "spring"].content {
  place_banner_1 {
  	alt,
  	photo {
    asset-> {
        url,
        "width": metadata.dimensions.width,
        "height": metadata.dimensions.height,
  			"ratio": metadata.dimensions.aspectRatio
      }
  	}
  },
  place_banner_2,
  place_banner_3...
}
AI Update

Yes! You can use the ellipsis operator (...) in GROQ to include all fields from an object without specifying each one individually. This is perfect for fetching image asset data.

Here's how you can simplify your query:

*[_id == "spring"].content {
  place_banner_1 {
    alt,
    photo {
      asset-> {
        ...,
        "width": metadata.dimensions.width,
        "height": metadata.dimensions.height,
        "ratio": metadata.dimensions.aspectRatio
      }
    }
  },
  place_banner_2 {
    alt,
    photo {
      asset-> {
        ...
      }
    }
  },
  place_banner_3 {
    alt,
    photo {
      asset-> {
        ...
      }
    }
  }
}

The ellipsis operator (...) expands to include all fields from the dereferenced asset document, giving you the url, metadata, and all other asset properties automatically.

Important tip about operator placement: The ellipsis is always evaluated first, regardless of where it appears in the projection. This means if you want to override or add custom fields, you should place the ellipsis first:

asset-> {
  ...,  // Place first to avoid it overriding your custom fields
  "width": metadata.dimensions.width,
  "height": metadata.dimensions.height,
  "ratio": metadata.dimensions.aspectRatio
}

If you place ... after your custom fields, it won't override them (since it's evaluated first anyway), but placing it first makes the intent clearer and is the recommended pattern.

You can also use this pattern to fetch all images used by a document by querying for references to sanity.imageAsset:

*[_id == "spring"] {
  "allImages": *[_type == "sanity.imageAsset" && references(^._id)]
}

This gives you all image assets that are referenced anywhere in your document, which can be useful for understanding asset usage across your content.

Show original thread
11 replies
well all these banners have the exact same fields so that'd be redundant to rewrite every file to fetch yea
Is it possible to migrate into an array, which you could then traverse?
meaning that I'd have to use it like
banners[0]
etc? If yes, I'd prefer to keep an object key if possible
user A
ideally if I could do something like this that'd be dope šŸ˜„
{
  // Seasons
  "spring": *[_id == "images_spring"][0].content {
  	[place_banner_1, place_banner_2, place_image_1] {
      alt,
      "image": photo.asset-> {
        url,
        "width": metadata.dimensions.width,
        "height": metadata.dimensions.height,
        "ratio": metadata.dimensions.aspectRatio
      }
    }
	}
}
or, eventually, a sort of shortcut to avoid repeating the fields inside of each so I can reuse a variable or something patterny
I asked about your use case and it doesn’t sound like there’s a way to achieve this sort of catch-all of keys (e.g.,
*[_id == "spring"].content.*.photo.asset->
). Using an array would let you traverse that array, saving you from having to specify all these keys more than once.
I asked about your use case and it doesn’t sound like there’s a way to achieve this sort of catch-all of keys (e.g.,
*[_id == "spring"].content.*.photo.asset->
). Using an array would let you traverse that array, saving you from having to specify all these keys more than once.
user N
could you send some example code? been following this thread since i was looking into something similar
Sure! but be careful, it hurts haha, took me 1/2h to figure out with the
dedent
thing:
// Sanity Images query
const query = dedent`
    *[_id == "images_${season}"][0].content {
        // Carousel
        // TODO

        // Banners
        ${[...Array(3)].map((_, i) => dedent`
            place_banner_${i + 1} {
                "alt": photo.alt,
                "image": photo.asset-> {
                    url,
                    "width": metadata.dimensions.width,
                    "height": metadata.dimensions.height,
                    "ratio": metadata.dimensions.aspectRatio
                }
            },
        `).join('')}

        // Image blocks
        ${[...Array(4)].map((_, i) => dedent`
            place_image_block_${i + 1} {
                ${['foreground', 'background'].map(image => dedent`
                    "${image}": ${image}.photo {
                        alt,
                        "image": asset-> {
                            url,
                            "width": metadata.dimensions.width,
                            "height": metadata.dimensions.height,
                            "ratio": metadata.dimensions.aspectRatio
                        }
                    },
                `).join('')}
            },
        `).join('')}
    }
`
technically it is the same code written a lot inside of the query, but visually it's not as bad as repeating 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?