How to make GROQ filter conditional when parameter is undefined in Sanity query?
export async function getPosts(start: number = 0, end: number = 9, _id?: string) {
const getPostsQuery = groq`
// Get posts That are in the selected category And order them by published date
*[_type == "post" && $categoryId in categories[]._ref] | order(publishedDate desc) {
title,
slug {
current
},
publishedDate,
shortDescription,
cardImage {
...,
asset-> {
...,
}
}
}[$start...$end]
`
return client.fetch<GetPostsQueryResult>(
getPostsQuery,
{ start, end, categoryId: _id },
{
next: {
tags: ['posts'],
revalidate: 60,
},
}
)
}It's specifically
$categoryId in categories[]._refthis part of the query that is fetching based on the passed ID.
Can I make this filtering conditional, and stop it from doing this filter when nothing is passed as an ID?
Yes, you can make that filter conditional! The select() function in GROQ is perfect for this. It works like a switch statement and lets you conditionally apply filters based on whether a parameter is defined.
Here's how to update your query:
const getPostsQuery = groq`
*[
_type == "post"
&& select(
defined($categoryId) => $categoryId in categories[]._ref,
true
)
] | order(publishedDate desc) {
title,
slug {
current
},
publishedDate,
shortDescription,
cardImage {
...,
asset-> {
...,
}
}
}[$start...$end]
`The key change is using select() with defined():
- If
$categoryIdis defined (not null), it applies the filter$categoryId in categories[]._ref - If
$categoryIdis not defined, it returnstrue, which means the filter passes for all documents
This way, when you pass in an _id, it filters by category. When you don't pass anything (or pass undefined), it returns all posts without applying the category filter.
The select() function evaluates conditions in order and returns the value of the first condition that's true, making it ideal for conditional parameter filtering like this.
Show original thread3 replies
Was this answer helpful?
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.