How AI is powering better personalization in e-commerce [with Vercel]. Sign up now

Sanity listen() receiving all document changes instead of filtered single document

9 repliesLast updated: Nov 30, 2025

Trying to listen to changes on single document, getting any changed document
Using the
Sanity JS client.listen method, we’re trying to listen to changes on a single document but are receiving any changed document, not just the intended target with matched field as specified in the GROQ filter.
We’ve tried signatures both with a without the “params” parameter, but are getting the same issue with both of the following query setups that attempt to listen only to the ‘show’ with matching ‘slug’ field:

Query only:

const showQuery = `*[_type == "show" && slug == "${this.slug}"][0]{field1, field2, ...}`;
sanity.client.listen(showQuery);
Query and params:

const showQuery = `*[_type == "show" && slug == $slug][0]{field1, field2, ...}`;
const showParams = { slug: `${this.slug}` };
sanity.client.listen(showQuery, showParams);
Both approaches fire updates with any changed document.

Can anyone help with tips/direction on how to restrict listener updates to a single intended record? Thanks!
AI Update

You've hit a common gotcha with Sanity's client.listen() method! The issue is that listener queries only use the top-level filter portion of your query - projections, slicing (like [0]), and other operations are ignored.

According to the Listen API documentation:

"Only the top-level filter portion of the query will be used, anything else including projection, subqueries, slicing or aggregation will be ignored."

So when you write:

const showQuery = `*[_type == "show" && slug == "${this.slug}"][0]{field1, field2, ...}`;

The listener is only seeing *[_type == "show" && slug == "${this.slug}"] and ignoring the [0] slice and the projection. This means you'll get events for all documents matching that filter.

The fix: Remove the [0] and projection from your listen query. Your filter is actually working correctly - you just need to handle the filtering on the client side:

const showQuery = `*[_type == "show" && slug.current == $slug]`;
const showParams = { slug: this.slug };

const subscription = client.listen(showQuery, showParams)
  .subscribe(update => {
    // The update.result will contain the full document after mutations
    const show = update.result;
    console.log('Show updated:', show);
  });

Important notes:

Show original thread
9 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.

Related contributions