How to expand image asset references in PortableText/BlockContent with GROQ?

7 replies
Last updated: Nov 30, 2025
So, I'm trying to render a PortableText with images in a React application (using @portabletext/react and Sanity v3). I have followed the ReadMe on how to create a custom react component to display images, but the BlockContent returned from my query contains objects of images with a reference to the
image->asset->_ref
instead of the expanded image url. How can I get the expanded image references directly from my GROQ query?
In other queries I can do
*[_type == "post"] { "image": image.asset->url }
but I'm not sure how to do this for BlockContent.
This is the blog template without any big modifications.
AI Update

When querying PortableText with image references, you need to use GROQ's conditional operator and the @ operator to expand inline references. Here's how to solve this:

The Solution

Use this GROQ query pattern to expand image references within your PortableText blocks:

*[_type == "post"] {
  title,
  body[]{
    ...,
    _type == "image" => {
      ...,
      "asset": @.asset->
    }
  }
}

How It Works

The key is using the @ operator, which refers to the root value of the current scope. When you iterate through the PortableText array with body[], the @ operator lets you access the current block object and dereference its asset.

Breaking it down:

  • body[] - Iterates through all blocks in your PortableText array
  • ... - Spreads all existing properties of each block
  • _type == "image" => {...} - Conditionally handles blocks that are images
  • @.asset-> - Dereferences the asset for the current image block

For Custom Reference Types

If you have custom reference types in your PortableText (like in the children array), use the same pattern:

children[]{
  ...,
  _type == 'orderReceiptPlaceholderRef' => {
    "reference": @->
  }
}

This approach works because:

  1. Some children are regular spans, others are references
  2. children[]-> would dereference everything (leaving non-references as null)
  3. children[] alone includes everything but doesn't expand references
  4. Using the conditional with @-> only dereferences when needed

You can find more examples of GROQ conditionals in the GROQ query cheat sheet, and this solution is based on a community discussion about this exact issue.

Show original thread
7 replies

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?