APIs and SDKs

Advanced client patterns with @sanity/client

Learn about mutation options, request cancellation, and other advanced patterns when using the Sanity JavaScript client.

This guide covers advanced patterns for working with @sanity/client, including mutation options that control how changes are applied, the retries the client performs on your behalf, and techniques for canceling in-flight requests.

These patterns apply to any mutation method: create(), patch(), delete(), and transaction().commit(). See Creating and updating documents and Creating transactions for the basics.

Mutation options

Control how mutations execute with options for visibility, dry runs, and array key generation. These options apply to any mutation method, not only transactions.

Visibility: sync, async, and deferred

The visibility option controls when mutations become visible to queries:

  • sync: The mutation completes and indexes before returning. Queries immediately see the changes. This is the default behavior.
  • async: The mutation returns immediately but indexes in the background. Queries may not see changes right away.
  • deferred: The mutation queues for later processing. Use this for non-critical updates or bulk operations.

Dry run mode

Test mutations without applying changes using dryRun: true. The API validates the mutation and returns what would happen, but does not modify any documents:

Auto-generate array keys

By default, the client automatically generates _key values for array items. Disable this with autoGenerateArrayKeys: false if you want to provide your own keys:

Automatic retries

@sanity/client retries some failed requests on its own. Retries are on by default, so you don't need to add your own backoff around a query.

The client retries a request when the response status is 429 Too Many Requests, 502 Bad Gateway, or 503 Service Unavailable, and the request is one of these:

  • A GET or HEAD request, such as getDocument().
  • A query to the /data/query endpoint, including a query long enough that the client sends it as a POST.

The client also retries DNS ENOTFOUND failures on idempotent requests, meaning GET and HEAD, using the same backoff. A hostname that never resolves, such as a mistyped project ID, takes the full retry sequence to fail rather than failing at once. Set maxRetries: 0 to fail immediately instead. This applies to @sanity/client v8 and later.

Mutations are not retried

Retry defaults

Two ClientConfig options control retries:

  • maxRetries: how many times to retry a failed request. Defaults to 5. Set it to 0 to turn retries off.
  • retryDelay: a function that receives the attempt number, starting at 0, and returns how long to wait in milliseconds. Defaults to exponential backoff with jitter: 100 * 2 ** attemptNumber plus a random 0 to 100 milliseconds.

With the defaults, the waits are roughly 100, 200, 400, 800, and 1,600 milliseconds, each plus up to 100 milliseconds of jitter. A request that exhausts all five retries fails after about 3.1 to 3.7 seconds.

Canceling requests

Cancel in-flight requests using AbortController or by unsubscribing from Observables. This is useful for cleaning up requests when components unmount or when user actions make a request obsolete.

Using AbortController

Pass an AbortSignal to any client method to enable cancellation:

Unsubscribing from Observables

When using the Observable API, unsubscribe to cancel the request:

React cleanup example

This example shows how to cancel requests when a React component unmounts:

Reference documentation

For the complete set of mutation options, error types, and client configuration, see the reference documentation for SanityClient and ClientConfig.

Was this page helpful?