
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storePerfect! The article actually covers your exact use case. When you have an array with mixed content (some references, some inline objects), you can use the coalesce() function with the @ operator.
Here's the solution:
*[_type == "page" && pageMetadata.slug == 'test'][0]{
pageBuilderComponents[]{
...coalesce(@->, @)
}
}How this works:
@ represents the current element in the array@-> attempts to dereference the current element (only works if it's a reference)coalesce(@->, @) tries to resolve as a reference first (@->), and if that returns null (because it's not a reference), it falls back to the original object (@)... expands all the fields from whichever result coalesce returnsThis pattern is mentioned in the Reference Access Operator documentation as the recommended approach for handling mixed content types in arrays.
Alternative approach if you want more explicit control:
*[_type == "page" && pageMetadata.slug == 'test'][0]{
pageBuilderComponents[]{
_type,
select(
defined(_ref) => @->,
!defined(_ref) => @
)
}
}This uses select() to check if the element has a _ref field (indicating it's a reference) and conditionally resolves it. However, the coalesce approach is cleaner and more idiomatic for this use case.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store