Adding reference in block array - how to expand with GROQ?
{
name: "body",
type: "array",
title: "Body",
of: [
{ type: "block" },
{ type: "image" },
{
title: "Class",
name: "jccClass",
type: "reference",
to: [{ type: "jccClass" }],
},
],
},*[_type == "post" && slug.current == $slug][0] {
_id,
title,
body,
"slug": slug.current
}{
"post": {
"_id": "50bc7aa9-f4af-424d-9184-fbabb2b826ed",
"body": [
{
"_key": "307f83dbbafb",
"_ref": "df6c5ee6-a80f-4e68-843a-501abaafc6ca",
"_type": "jccClass"
},
...
],
"slug": "post-one",
"title": "Post Number One"
}
}Thanks!
You can absolutely dereference (expand) those references directly in your GROQ query! The key is using the -> operator, which tells GROQ to follow the reference and pull in the actual document data.
For your specific case with references inside a body array (portable text), you'll want to use array projection to selectively expand only the reference items. Here's how to modify your query:
*[_type == "post" && slug.current == $slug][0] {
_id,
title,
body[] {
...,
_type == "jccClass" => @->
},
"slug": slug.current
}This syntax works by:
body[]- iterates over each item in the body array...- spreads all the existing properties (keeps blocks, images, etc. intact)_type == "jccClass" => @->- conditionally dereferences: when the item type is "jccClass", the@refers to the current item and->follows the reference
If you want to control which fields from the referenced jccClass document get returned (recommended for performance), you can be more specific:
*[_type == "post" && slug.current == $slug][0] {
_id,
title,
body[] {
...,
_type == "jccClass" => @-> {
_id,
title,
description,
// whatever fields you need from jccClass
}
},
"slug": slug.current
}This approach is much more efficient than having your component fetch each reference separately, as it resolves everything in a single query. The Content Lake will handle all the dereferencing server-side.
The -> operator works for any reference type in Sanity, and the conditional projection pattern (_type == "something" => ...) is the standard way to handle mixed arrays like portable text where you have blocks, images, and custom reference types all together.
Show original thread9 replies
Was this answer helpful?
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.