How to fetch blogPosts filtered on category in Sanity.io.

3 replies
Last updated: Feb 6, 2024
How do I fetch all
blogPosts
filtered on
category
? (
categories
is an array of references to
blogPostCategory
)
I have tried:

"blogPosts": *[_type == "blogPost" && categories[]->slug.current == "news"] { ... }
and:

"blogPosts": *[_type == "blogPost" && (categories[]->slug.current)[@ in ["news"]]] { ... }

🙏
AI Update

Your first query is very close! The key to filtering an array of references in GROQ is using the @ operator (parent operator) to filter within the array itself. Here's how to solve your problem:

Simple approach using in:

*[_type == "blogPost" && "news" in categories[]->slug.current] {
  ...
}

This uses the in operator to check if "news" exists in the array of dereferenced category slugs.

More flexible approach using @ (recommended):

*[_type == "blogPost" && count(categories[@->slug.current == "news"]) > 0] {
  ...
}

The @ operator is crucial here - it refers to the current element in the array iteration. So categories[@->slug.current == "news"] means "filter the categories array to only include references where the dereferenced slug.current equals 'news'".

This pattern was demonstrated in this community answer and is particularly powerful when you need multiple conditions.

For multiple categories:

*[_type == "blogPost" && count(categories[@->slug.current in ["news", "updates"]]) > 0] {
  ...
}

Adding more conditions (like checking if items are disabled):

*[_type == "blogPost" && count(categories[@->slug.current == "news" && !@->disabled]) > 0] {
  ...
}

Why your original attempts didn't work:

  • categories[]->slug.current == "news" tries to compare the entire array result to a single value, rather than filtering within the array
  • (categories[]->slug.current)[@ in ["news"]] has the syntax backwards - you need to filter before dereferencing

Important note: These patterns require API version v2021-03-25 or later. If you're using an older API version, you'll need to update your client configuration to use the newer API version.

"blogPosts": *[_type == "blogPost" && "news" in categories[]->slug.current] { ... }
does that work?
Yes!! Oh man was it just a js syntax misstake 😅 Thanks alot

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.

Was this answer helpful?