Configure @sanity/client in Functions
Learn to use the JavaScript client in a Sanity Function.
Functions have the ability to connect back to Sanity and manipulate not only the incoming document, but any document in your dataset. By including details about your project in the context, Functions enable you to configure a @sanity/client
instance and interact with any Sanity API.
In this guide, you'll learn to install and configure @sanity/client
in a Sanity Function. Then you'll use it to make interact with your project dataset.
Prerequisites:
- Complete the Functions quick start, or be comfortable writing and deploying a Sanity Function.
sanity
CLI v3.92.0 or higher is recommended to interact with Blueprints and Functions. You can always run the latest CLI commands withnpx sanity@latest
.
Create a function
If you don't already have a Blueprint and function set up, create them now.
Initialize a Blueprint:
npx sanity@latest blueprints init
Add a function:
npx sanity blueprints add function
In this example, we'll set the function to trigger on Document Publish, use TypeScript, and set the name to clientExample.
✔ Enter function name: clientExample
✔ Choose function type: Document Publish
✔ Choose function language: TypeScript
This creates a function in the functions/clientExample
directory.
Add @sanity/client
to the function
To install the Sanity client, add it to your project at the blueprints root (where your sanity.blueprint.ts
file is).
npm install @sanity/client
pnpm add @sanity/client
Function dependencies
Functions can be self-contained, managing their own dependencies, or share dependencies with other functions in the Blueprint. This guide adds dependencies at the Blueprint level, where all functions can import them.
If you prefer, you can keep each function self-contained by adding dependencies directly to individual function folders. To do so, navigate to the function folder before installing the package. In this case, the function will only use it's local dependencies.
Learn more in the guide on managing function dependencies.
Once the install completes, open the function's index.ts
file and update the starter code.
- Import
createClient
. - Use
context.clientOptions
to configure the client. - Make and log a request to the API to test the client.
import { documentEventHandler } from '@sanity/functions'
import { createClient } from '@sanity/client'
export const handler = documentEventHandler(async ({ context, event }) => {
const client = createClient({
...context.clientOptions,
apiVersion: '2025-05-08',
})
const posts = await client.fetch('*[_type == "post"]')
console.log(posts)
})
import { createClient } from '@sanity/client'
export async function handler({context, event}) {
const client = createClient({
...context.clientOptions,
apiVersion: '2025-05-08',
})
const posts = await client.fetch('*[_type == "post"]')
console.log(posts)
}
The context includes a clientOptions
object with details about your project, dataset, and a robot token. Use clientOptions
along with any preferred settings to create a new client. Aside from the values included with clientOptions
, you must also set your preferred apiVersion
.
Obfuscated tokens
Logs will obfuscate clientOptions.token
by replacing parts of the token with asterisks. This is limited to logging, and you can safely use the token to make API calls.
You can read more about clientOptions and all available properties in the handler reference.
Additional client-specific configuration options, and usage guides for the JavaScript client are available in the @sanity/client
readme.
Preventing writes during testing
The sanity functions test
and dev
commands simulate a function invocation, but they still execute your code. This can lead to mutations. To prevent this, you can take advantage of context.local
.
You can wrap mutations in a conditional check to limit their execution to production only.
// Check if function context is NOT test/dev
if (!context.local) {
await client.createOrReplace(doc)
}
You can also use context.local
with the dryRun
or noWrite
options for various mutations and actions.
// will set dryRun to true in test / dev
client
.patch('bike-123')
.set({inStock: false})
.inc({numSold: 1})
.commit({ dryRun: context.local })
// will set dryRun to true in test
client.action({
actionType: 'sanity.action.document.create',
publishedId: 'bike-123',
attributes: {name: 'Sanity Tandem Extraordinaire', _type: 'bike', seats: 1},
ifExists: 'fail',
},
{dryRun: context.local}
)
client.agent.action.generate({
schemaId: 'your-schema-id',
documentId: 'your-document-id',
instruction: 'Write a summary for the following topic: $topic',
instructionParams: {
topic: 'Grapefruit',
},
target: {path: ['body']},
noWrite: context.local
})
Tips for using the client
- Be cautious mutating the incoming document—the one that triggered the function—in a way that will trigger it again.
- Don't re-fetch the
event
document unless you need. Use the incoming payload to save a request. - The Sanity client isn't required to make requests to Sanity. If you're focused on the fastest, lightest function possible, you can build API calls manually with Node's
fetch
and the token, projectId, and dataset fromcontext.clientOptions
.
Was this page helpful?