Querying references and displaying them in Sanity Studio.
No, references in Sanity do not store parent data - they only store the ID of the referenced document in a _ref field. A reference is essentially just a pointer to another document.
For example, when you have a reference field, it's stored like this:
{
"_id": "alice",
"_type": "employee",
"name": "Alice Anderson",
"department": {"_ref": "engineering"}
}Notice that department only contains {"_ref": "engineering"} - no actual department data is stored in the parent document.
Querying References with GROQ
To retrieve the actual referenced document data, you use the dereference operator -> in GROQ:
*[_type == "employee"] {
name,
department->
}This resolves the reference and returns the full department document:
{
"name": "Alice Anderson",
"department": {
"_id": "engineering",
"_type": "department",
"name": "Engineering"
}
}You can also project specific fields from the referenced document:
*[_type == "employee"] {
name,
department->{
name,
location
}
}Array References
For arrays of references, dereference all items like this:
*[_type == "footer"] {
socials[]->{
name,
url
}
}Reverse Lookups
If you need to find documents that reference a specific document (reverse lookup), use the references() function:
*[_type == "artist"][0] {
name,
"events": *[_type == "event" && references(^._id)] {
name
}
}This finds all events that reference the current artist.
The key takeaway: references are lightweight pointers that only store IDs, and you use the -> operator to fetch the actual referenced document data when querying.
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.