Querying for image URLs in a content array in Sanity

16 replies
Last updated: Jan 15, 2023
Howdy. This might be a dumb question but what's the best way to get the url of an image that is returned inside a content array? Right now all I can see from the return is this:

2: Object { _key: "00af18309329", _type: "image", asset: {…} }

_key: "00af18309329"

_type: "image"

asset: Object { _ref: "image-efd90ba5e6942927a7bb04b72e8b7bb74494dd63-4896x3264-jpg", _type: "reference" }

_ref: "image-efd90ba5e6942927a7bb04b72e8b7bb74494dd63-4896x3264-jpg"

_type: "reference"

<prototype>: Object { … }

<prototype>: Object { … }
How would I add the Image Url to this return?

Here are my queries:



const entryFields = groq`
  _id,
  title,
  date,
  excerpt,
  content,
  topics,
  "slug": slug.current,
`

export const indexQuery = groq`
*[_type == "entry"] | order(date desc, _updatedAt desc) {
  ${entryFields}
}`
Thanks!
Nov 30, 2022, 9:33 PM
Hey
user B
! You can dereference an image's asset to get all of its data. You can read about dereferencing here . Given that the object you shared has a key, I'm assuming it's inside of an array, so querying it would look like this:
<name-of-image-array>[]{
  'imageUrl': asset->url
}
Nov 30, 2022, 10:37 PM
Thank you so much! I will give this a go. Appreciate it.
Nov 30, 2022, 10:38 PM
How could I adjust this to work with an array of different types? Where I only need to query for the image url if the type is an image.
This is the array:

{name: 'content', 
title: 'Content', 
type: 'array', 
of: [{ type: 'block'}, 
{type: 'image'}, 
{type: 'mux.video'}, 
{type: link.name}
              ]},
Nov 30, 2022, 10:53 PM
You can set up a conditional one of the methods here . That way you can control what your query does depending on the type.
Dec 1, 2022, 12:05 AM
TYSM. Would you mind checking the code below for my query and telling me where I'm messing up? I am trying to return all of the content array with the image type dereferenced to include the image url. Content is an array of mixed types.

*[_type == "entry"] | order(date desc, _updatedAt desc) {
  _id,
  title,
  date,
  excerpt,
  content[]{
    _type == "image" => { 
      @-> {url}
    }
  },
  topics,
  "slug": slug.current,
}
And this is the error:
ClientError: Attribute or a string key expected
Dec 1, 2022, 6:46 PM
Ah, so if you're getting a field from a reference you need to give it a name. Something like this should work:
*[_type == "entry"] | order(date desc, _updatedAt desc) {
  _id,
  title,
  date,
  excerpt,
  content[]{
    _type == "image" => { 
      'url': @->url
    }
  },
  topics,
  "slug": slug.current,
}
Dec 1, 2022, 8:24 PM
Thx! Yeah that works partially, the issue is that it only will return data for the items in the array with type image. How do I get all the data for the other types? Thanks!
Dec 1, 2022, 8:45 PM
You can use the spread operator to add in all those other fields:
*[_type == "entry"] | order(date desc, _updatedAt desc) {
  _id,
  title,
  date,
  excerpt,
  content[]{
    ..., //this means add all fields
    _type == "image" => { 
      'url': @->url
    }
  },
  topics,
  "slug": slug.current,
}
Dec 1, 2022, 8:47 PM
OHHHH I'm so dumb. I totally thought "...," just meant 'put whatever here'
Thank you!'
Dec 1, 2022, 8:52 PM
Haha, I feel like that's a totally understandable interpretation.
Dec 1, 2022, 9:05 PM
Thanks again! Got that all working but ran into another roadblock. I created a type called "doubleImage" which is an object with two image fields ( 'leftImage' and 'rightImage'). I'm trying to get the url from each image but can't seem to get the syntax right... As you see below my thinking was to add a condition for the type 'doubleImage' followed by one for 'image' to get the url for each image in the object, but something is not right.

*[_type == "entry"] | order(date desc, _updatedAt desc) {
  _id,
  title,
  date,
  excerpt,
  content[]{
    ...,
    _type == "image" => { 
      'url': asset->url,
      ...,
    },
    _type == "doubleImage" => { 
      _type == "image" => { 
        'url': asset->url,
        ...,
      },
      ...,
    },
  },
  topics,
  "slug": slug.current,
}
The portion of the return with the array in question:

content: Array(7) [ {…}, {…}, {…}, … ]

0: Object { _key: "93bf8b952054", _type: "block", style: "normal", … }

1: Object { _key: "00af18309329", _type: "image", url: "<https://cdn.sanity.io/images/ax2b1emw/production/efd90ba5e6942927a7bb04b72e8b7bb74494dd63-4896x3264.jpg>", … }

2: Object { _key: "7a8246b69363", _type: "break", break: true }

3: Object { _key: "d2288b5aa74b", _type: "block", style: "normal", … }

4: Object { _key: "9f0f081a7cf6", _type: "block", style: "normal", … }

5: Object { _key: "02cd832b3f4f", _type: "block", style: "normal", … }

6: Object { _key: "347006c9a303", _type: "doubleImage", leftImage: {…}, … }

_key: "347006c9a303"

_type: "doubleImage"

leftImage: Object { _type: "image", asset: {…} }

_type: "image"

asset: Object { _ref: "image-639eb5a2780601edb6dc19bf20f52efb2c37588f-4500x3000-jpg", _type: "reference" }

_ref: "image-639eb5a2780601edb6dc19bf20f52efb2c37588f-4500x3000-jpg"

_type: "reference"

<prototype>: Object { … }

<prototype>: Object { … }

rightImage: Object { _type: "image", asset: {…} }
Dec 2, 2022, 11:04 PM
I think you need something like:
*[_type == "entry"] | order(date desc, _updatedAt desc) {
  _id,
  title,
  date,
  excerpt,
  content[]{
    ...,
    _type == "image" => { 
      'url': asset->url,
      ...,
    },
    _type == "doubleImage" => { 
      ...,
      'leftImageUrl':leftImage.asset->url,
      'rightImageUrl':rightImage.asset->url
    },
  },
  topics,
  "slug": slug.current,
}
Sidenote: when using the spread operator, make sure you put it above any fields your naming so you don't accidentally overwrite them.
Dec 2, 2022, 11:45 PM
TYSM! I will give this a go. I really appreciate the help! And thanks for the tip as well. That is definitely good to know. I hope you have a good weekend.
Dec 3, 2022, 1:14 AM
That worked! Thanks! This is for my first freelance project btw. I have enjoyed using Sanity!
Dec 3, 2022, 1:23 AM
Congrats on your first freelance project! Huge achievement! Have a good weekend as well!
Dec 3, 2022, 7:09 PM
Hey
user M
, I have a similar issue. But all I want to do is create an
excerpt
field that I can call in my front end as

{{project.excerpt}}
Ideally, the excerpt is the first 100 characters from a project.body.

*[_type == "article"] {
   "excerpt": array::join(string::split((pt::text(body)), "")[0..255], "") + "..."
}
This excerpt didn't work out for me.
Jan 15, 2023, 2:31 PM

Sanity– build remarkable experiences at scale

Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.

Was this answer helpful?