How to query posts by dynamically provided category reference in Sanity?
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.
Show original thread15 replies
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.