How to query referenced document with image in Portable Text?

7 replies
Last updated: Jun 3, 2021
Kia ora! I’m trying to expand the logic on this page to query a reference to a document that contains an image, to be able to display that image within my portable text.
I have the image document (
photo
) insertable in studio, and am now figuring out my query.
I’m trying something similar to this fragment from that page:


*[_type == "post"]{
  ...,
  body[]{
    ...,
    markDefs[]{
      ...,
      _type == "internalLink" => {
        "slug": @.reference->slug
      }
    }
  }
}

Here’s my query:


*[_type == "collection" && slug.current == "5-frames-with-a-yashica-a-and-ilford-xp-2-super-400"]{
  title, description[]{

...,

_type == "reference" => {

"slug": @.reference->slug, "image": @.reference->image.asset}

}}[0]

In vision, the query runs but the
”type”:  “reference”
objects returned aren’t outputting the slug or image key that I’m trying to query for. Is there something missing from my syntax?
AI Update

Looking at your query, I can see the issue. When you're trying to expand references within an array like description[], you need to handle the projection differently. The @ symbol refers to the current item in the array iteration, and when you use @.reference->, you're trying to dereference, but the syntax needs adjustment.

Here's the corrected approach:

*[_type == "collection" && slug.current == "5-frames-with-a-yashica-a-and-ilford-xp-2-super-400"]{
  title,
  description[]{
    ...,
    _type == "reference" => @->{
      slug,
      "imageUrl": image.asset->url
    }
  }
}[0]

The key differences:

  1. Use @-> instead of @.reference-> - The @ symbol already represents the current reference object, so you just need to dereference it directly with @->

  2. Projection after dereferencing - After @->, you can project the fields you want from the referenced document

If your portable text has mixed content (some references, some regular blocks), you might want to conditionally handle both:

*[_type == "collection" && slug.current == "5-frames-with-a-yashica-a-and-ilford-xp-2-super-400"]{
  title,
  description[]{
    _type != "reference" => @,
    _type == "reference" => @->{
      slug,
      "imageUrl": image.asset->url
    }
  }
}[0]

This pattern (shown in the conditionals section of the query cheat sheet) returns the inline object for non-references and expands the referenced document for references.

The reason your original query wasn't working is that @.reference doesn't exist - @ itself is the reference object, which has _ref and _type properties. The -> operator is what follows the reference to get the actual document.

Show original thread
7 replies
By updating my schema to use an object with a reference field instead of a direct reference, I can access what I need in the query - but in the studio it looks like this, which is less than ideal!

{
                    type: 'object',
                    name: 'photo',
                    title: 'Photo reference',
                    fields: [
                        {
                            type: 'reference',
                            name: 'reference',
                            to: {
                            type: 'photo',
                        }}
                    ]
            }
Aaaaaand I think I figured it out! I took out the object and made it a direct reference, but made sure I named it (
photo
) and now the query runs smoothly, and it looks nice in studio!
Great 🙂. I find that the kitchen sink example have a nice patterns to use: https://github.com/sanity-io/sanity-template-kitchen-sink/tree/main/template/studio . The studio i am working on, uses a lot of images in text: https://github.com/tarjelavik/sanity-exhibition-nansen/blob/main/studio/schemas/texts/blockContent.js both as references and objects.
Hi again everyone! I’m having a funny issue where this code and query that was working, is no longer! All of a sudden I’m getting a plain reference object instead of a full object with the keys I’m querying for.
What’s especially odd is that my deployed code is working (mostly) as it should - it’s able to display one of the images I’m querying for - but locally the site won’t build at all because the query isn’t returning as expected!

Any idea what might be happening here, or what I’m missing?
Have you updated the studio? Could it be a change in API version?
I think there must be a difference in my local studio vs what’s deployed, but looking at my version control, the only difference is in the relevant schema - and it seems both versions don’t work!
I think there must be a difference in my local studio vs what’s deployed, but looking at my version control, the only difference is in the relevant schema - and it seems both versions don’t work!

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?