Querying references in Sanity: how to search posts by category
Great question! Filtering posts by category is a common pattern in Sanity. Based on your schema where posts have an array of category references, here's how to query all posts for a specific category using GROQ:
The Solution
The key is using the references() function in GROQ. Here's the query:
*[_type == "post" && references($categoryId)]Where $categoryId is a parameter you pass in with the _id of the category you want to filter by.
Complete Example
If you want to include the category details in your results, you can dereference it:
*[_type == "post" && references($categoryId)] {
_id,
title,
categories[]->
}The -> operator dereferences the category references, giving you the full category documents instead of just the reference IDs.
Filtering Out Drafts
In production, you'll want to exclude draft documents:
*[_type == "post" && !(_id in path("drafts.*")) && references($categoryId)]Using with Client Code
Here's how you'd use this with the Sanity client:
const posts = await client.fetch(
`*[_type == "post" && references($categoryId)] {
_id,
title,
categories[]->
}`,
{ categoryId: 'your-category-id-here' }
)The references() function works perfectly with arrays of references - it checks if any item in your categories array references the provided ID. Check out the GROQ parameters documentation for more details on passing parameters to your queries.
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.