GROQ: Making query parameters optional for conditional filtering

18 replies
Last updated: Jan 28, 2026
Sanityland! Is there a way to make GROQ params optional?
ie. I want to conditionally provide a filtering param to a GROQ query. If no param is provided, don't filter. If provided, filter.

This is my current solution:

*[_type == 'feed' ${id ? ' && _id == $id' : ''}]
Is there a way to do this without JS template literals?
AI Update

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 thread
18 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.

Was this answer helpful?