Upgrade @sanity/client from an older major version
Find which @sanity/client version you run, why pre-v3 clients with a token skip the API CDN, and what changed in each major version.
Each major version of @sanity/client changes some defaults or requirements. On a project that still runs an old major version, those changes decide whether your queries reach the API CDN, how failed requests are handled, and which documents your queries return.
This guide shows how to find which version you run, explains the pre-v3 behavior that sends token-authenticated queries to the live API, and lists what to update for each major version.
Prerequisites:
- Access to the project's
package.jsonand lockfile. - Node.js 22.12 or later to run v8. If you can't upgrade Node.js, upgrade to v7, which runs on Node.js 20.
Check which version of @sanity/client you run
List every installed copy of the client. Other packages can depend on their own, older copy, so check each line of the output, not only your direct dependency:
npm ls @sanity/clientTo check the behavior instead of the version number, read the resolved configuration from a client instance. client.config().useCdn returns the value the client actually uses, which can differ from the value you passed in.
Tokens turn off the API CDN before v3
In @sanity/client v2 and earlier, setting a token turns useCdn off, even when you pass useCdn: true. The client sends every query to the live, uncached API at api.sanity.io, so token-authenticated traffic never benefits from the API CDN and counts against the live API's rate limits. A frontend that sends a token on every request can hit 429 Too Many Requests responses while its configuration says useCdn: true.
In Node.js, v2 and earlier log a warning when you create the client:
You have set `useCdn` to `true` while also specifying a token. This is usually not what you want. The CDN cannot be used with an authorization token, since private data cannot be cached. See https://docs.sanity.io/help/js-client-usecdn-token for more information.In a browser on a domain other than localhost, the client logs nothing, so the switch to the live API goes unnoticed.
Starting with v3.0.0, a client with a token and useCdn: true sends queries to the API CDN at apicdn.sanity.io. The API CDN caches authenticated responses separately for each token. To fix the behavior, upgrade to v3 or later; the latest major version is the recommended target.
The same configuration on v2 and on v8:
const sanityClient = require('@sanity/client')
// On v2 and earlier, the token turns useCdn off.
// Every query goes to the live API at api.sanity.io.
const client = sanityClient({
projectId: '<your-project-id>',
dataset: 'production',
token: process.env.SANITY_API_READ_TOKEN,
useCdn: true,
})
console.log(client.config().useCdn) // falseimport {createClient} from '@sanity/client'
export const client = createClient({
projectId: '<your-project-id>',
dataset: 'production',
apiVersion: '2026-03-01',
token: process.env.SANITY_API_READ_TOKEN,
useCdn: true,
})
console.log(client.config().useCdn) // trueChoose useCdn for each token client
After the upgrade, a token client with useCdn: true can receive cached responses. If a client needs the freshest data on every request, such as a client that previews drafts, set useCdn: false on that client explicitly.
In every version, withCredentials: true turns the API CDN off.
What changed in each major version
Read every section between your current version and the version you upgrade to. Each section links to the full release notes or migration guide in the @sanity/client repository.
v3
- A
tokencombined withuseCdn: trueuses the API CDN instead of the live API. - Requires Node.js 12 or later.
- Removes the deprecated
mergepatch operation and the deprecateddocumentproperty on theassets.uploadresponse. client.observable.fetch()returns a cold observable.
Details: v3.0.0 release notes.
v4
- Expands ES module support. Some bundler and runtime setups might need configuration changes.
Details: v4.0.0 release notes.
v5
- Replaces the default export with the named export
createClient. Changeimport sanityClient from '@sanity/client'toimport {createClient} from '@sanity/client'. From v5.2.1, the default export works again, but it's deprecated and logs a warning. - Requires Node.js 14.18 or later and no longer ships ES5 output.
- Removes
client.assets.getImageUrl()(use@sanity/image-url),client.assets.delete()(useclient.delete()), andclient.clientConfig(useclient.config()).
Details: Migrating from v4.
v6
useCdndefaults totrue. SetuseCdn: falseto keep querying the live API.- Retries
GETandHEADrequests and queries automatically when the API responds with429,502, or503. Also retriesGETandHEADrequests on network errors. If your application has its own retry logic, remove it or setmaxRetries: 0. See Automatic retries.
Details: Migrating from v5.
v7
- Requires Node.js 20 or later.
Details: v7.0.0 release notes.
v8
- Requires Node.js 22.12 or later and ships as ES modules only.
require('@sanity/client')still works on Node.js 22.12 or later. - TypeScript projects need
moduleResolutionset tonode16,nodenext, orbundler. - Removes the
requesteroption, the per-requestproxyoption, and the UMD bundle. - Retries DNS
ENOTFOUNDerrors forGETandHEADrequests. SetmaxRetries: 0to fail immediately. - Adds the HTTP status text to
ClientErrorandServerErrormessages, for exampleHTTP 400 Bad Request. Update any code that matches on error message text.
Details: Migrating from v7.
Set apiVersion to control the default perspective
Which documents a query returns by default depends on the apiVersion you set, not on the client's major version. Requests with an apiVersion earlier than 2025-02-19 use the raw perspective, which returns drafts alongside published documents when the request includes a token. From 2025-02-19, the default is published.
Clients older than v2.7.0 have no apiVersion option and always use API version v1. When you upgrade, set apiVersion to a fixed date and test your queries against it. See API versioning.
Fix the ERR_REQUIRE_ESM error after upgrading to v8
If require('@sanity/client') fails with Error [ERR_REQUIRE_ESM]: require() of ES Module, the project usually runs v8 on a Node.js version earlier than 22.12. When npm installs v8 on those versions, it also warns npm warn EBADENGINE Unsupported engine. Upgrade Node.js to 22.12 or later. If you can't upgrade Node.js, install v7 with npm install @sanity/client@7. v7 runs on Node.js 20 or later.
Next steps
- To set up a new client on the current version, see Getting started with @sanity/client.
- To tune automatic retries or cancel requests, see Advanced client patterns with @sanity/client.
- To choose a perspective for your queries, see Querying content with @sanity/client.
Was this page helpful?
Feedback submitted, thanks for helping us improve the docs. Have you tried these alternatives?