Is there a GROQ Query where References in a PortableText Array of Blocks Are Also Resolved?

9 replies
Last updated: Jun 5, 2020
Hello! Is there some GROQ query where references in a PortableText array of blocks are also resolved? I haven't found a way to address them in my projection.
AI Update

Yes! You can resolve references within PortableText arrays using the @ operator combined with conditionals. The @ operator refers to the root value of the current scope, which is perfect for handling mixed content where some items are references and others aren't.

Here's the pattern you'll want to use:

*[_type == "yourDocType"] {
  content[]{
    ...,
    _type == 'yourReferenceType' => {
      'resolved': @->
    }
  }
}

For example, if you have a PortableText array with custom reference blocks mixed with regular text spans, you can do:

{
  "content": content[]{
    ...,
    _type == 'orderReceiptPlaceholderRef' => {
      'referenceData': @->
    }
  }
}

The key points:

  1. Use @-> instead of just -> - The @ operator targets the current item in the array iteration, then -> dereferences it
  2. Conditionals preserve non-reference items - Items that don't match your reference type condition will pass through with the ... (spread operator)
  3. Project the resolved reference - You typically want to give the resolved data a field name like 'referenceData': @->

This approach works because:

  • children[]-> would try to dereference everything, leaving non-references as null
  • children[] alone includes everything but doesn't resolve references
  • The conditional with @-> selectively resolves only the reference types while preserving everything else

You can find more details about GROQ conditionals in the query cheat sheet and learn about the reference access operator (->) in the GROQ joins specification.

Hi there!
One way would be to use conditionals to check for block type, and resolve the references there. Take a look at the last example here:
https://www.sanity.io/docs/query-cheat-sheet#conditionals-64a36d80be73
Thanks
user J
! This looks like what we need. But we're still struggling to connect the dots πŸ™‚ We have an array of blocks and a custom reference type, like so:

{"_type": "block",
 "children":
 [{"_type": "span",
   "marks": [],
   "text": "Takk for din bestilling "}
  {"_ref": "0f65906e-05d1-48e6-a2cd-9a6414c874ec",
   "_type": "orderReceiptPlaceholderRef"}
  {"_type": "span", "marks": [], "text": "!"}],
 "markDefs": [],
 "style": "normal"}
It's not clear how to "point" (e.g.
->
) to inline the reference when it's just a member of the array:

children[]{
  ...,
  _type == 'orderReceiptPlaceholderRef' => {
    ->
  }
}

If that makes sense, heh
Specifically, the problem is that some children are references, others not. So
children[]->
unfurls the references, but leave other blocks null, while
children[]
include all children, but does not inline references 🀯
I this case you can use the
@
operator which refers to the root value of the current scope.
So

children[]{
  ...,
  _type == 'orderReceiptPlaceholderRef' => {
    @->
  }
}
should do it
It might be that you need to project the reference like so:
children[]{
  ...,
  _type == 'orderReceiptPlaceholderRef' => {
    'referenceOrWhateverYouWantToCallIt': @->
  }
}
hah, learned something new!
Last one worked, 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?