
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeThe 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.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store