GROQ: Making query parameters optional for conditional filtering
The approach you're using with template literals works, but there is a better way using GROQ's built-in select() function for conditional logic!
Here's how to handle optional parameters directly in GROQ:
*[
_type == 'feed'
&& select(
defined($id) => _id == $id,
true
)
]The select() function evaluates conditions in order and returns the result of the first matching condition. When $id is defined, it applies the filter _id == $id. When it's not defined, it returns true, which effectively means "no filter applied."
Important caveat: In GROQ, parameters cannot be undefined - they must either be present with a value or explicitly passed as null. So you'd call it like:
// With an ID
await client.fetch(query, { id: 'some-id' })
// Without an ID
await client.fetch(query, { id: null })Alternative approach (arguably cleaner for this specific case): Build the query conditionally in your JavaScript, but still use parameters for the actual values:
const query = id
? `*[_type == 'feed' && _id == $id]`
: `*[_type == 'feed']`
const params = id ? { id } : {}
const data = await client.fetch(query, params)This approach from the Sanity documentation keeps your GROQ cleaner while still using parameters for safety. The key advantage of using $id instead of template literal interpolation is security and proper escaping - parameters are JSON literals that can't contain GROQ expressions, preventing injection attacks.
Show original thread18 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.