Creating and updating documents with @sanity/client
Learn how to create, update, and patch documents with @sanity/client, including array manipulation, chained operations, and conditional updates.
The @sanity/client library provides methods for creating and modifying documents in your dataset. This guide covers the create, createOrReplace, createIfNotExists, and patch methods with practical examples for each.
Validation is client-side only
Schema validation rules only run in Sanity Studio. Mutations submitted through the API or client libraries are not checked against your validation rules. See Schema validation and the Content Lake for details.
Prerequisites
All mutation methods require an authenticated client with a write token and return promises that resolve with the created or updated document. See Getting started with @sanity/client for setup instructions.
Creating documents with client.create()
The create() method creates a new document in your dataset. Sanity automatically generates a unique _id for the document unless you provide one.
import {createClient} from '@sanity/client'
const client = createClient({
projectId: 'YOUR_PROJECT_ID',
dataset: 'YOUR_DATASET',
useCdn: false,
token: 'your-token',
apiVersion: '2026-03-01'
})
// Create a new document
try {
const newPost = await client.create({
_type: 'post',
title: 'Getting started with Sanity',
slug: {
_type: 'slug',
current: 'getting-started'
},
publishedAt: new Date().toISOString()
})
console.log('Created document:', newPost._id)
} catch (error) {
console.error('Failed to create document:', error.message)
}You can also specify a custom document ID:
const newPost = await client.create({
_id: 'post-123',
_type: 'post',
title: 'My custom ID post'
})Creating or replacing with client.createOrReplace()
The createOrReplace() method creates a new document or completely replaces an existing one if a document with the specified _id already exists. This is useful for idempotent operations where you want to ensure a specific document state.
// This will create the document if it doesn't exist,
// or replace it entirely if it does
const post = await client.createOrReplace({
_id: 'post-123',
_type: 'post',
title: 'Updated title',
slug: {
_type: 'slug',
current: 'updated-slug'
},
publishedAt: new Date().toISOString()
})
console.log('Document created or replaced:', post._id)The createOrReplace() method replaces the entire document. Any fields not included in the new document will be removed. Use patch() if you want to update specific fields while preserving others.
Creating if not exists with client.createIfNotExists()
The createIfNotExists() method creates a document only if no document with the specified _id exists. If the document already exists, the operation does nothing and returns the existing document.
// This will only create the document if it doesn't exist
const post = await client.createIfNotExists({
_id: 'post-123',
_type: 'post',
title: 'My post',
slug: {
_type: 'slug',
current: 'my-post'
}
})
// If the document already exists, it returns the existing document
// without modifying itThis method is particularly useful for initialization scripts or ensuring default documents exist without overwriting user modifications.
Patching documents with client.patch()
The patch() method lets you update specific fields in an existing document without replacing the entire document. You can chain multiple operations together to perform complex updates.
// Update specific fields in a document
const updatedPost = await client
.patch('post-123')
.set({title: 'Updated title'})
.commit()
console.log('Updated document:', updatedPost)The commit() method executes the patch operation. You can chain multiple patch operations before calling commit().
Setting fields with .set()
The set() method sets or overwrites field values. You can set multiple fields at once or use dot notation to set nested fields.
// Set multiple fields
const result = await client
.patch('post-123')
.set({
title: 'New title',
publishedAt: new Date().toISOString(),
'author.name': 'Jane Doe'
})
.commit()
// Set nested fields using dot notation
const nested = await client
.patch('post-123')
.set({'metadata.views': 100})
.commit()Setting only if missing with .setIfMissing()
The setIfMissing() method sets field values only if the fields don't already exist or are null. This is useful for setting default values without overwriting existing data.
// Set default values only if they don't exist
const result = await client
.patch('post-123')
.setIfMissing({
views: 0,
likes: 0,
publishedAt: new Date().toISOString()
})
.commit()
// If 'views' already has a value, it won't be changed
// If 'views' is null or doesn't exist, it will be set to 0Removing fields with .unset()
The unset() method removes fields from a document. You can remove multiple fields by passing an array of field paths.
// Remove a single field
const result = await client
.patch('post-123')
.unset(['draft'])
.commit()
// Remove multiple fields at once
const multiUnset = await client
.patch('post-123')
.unset(['draft', 'internalNotes', 'metadata.temp'])
.commit()Incrementing and decrementing with .inc() and .dec()
The inc() and dec() methods increment or decrement numeric field values. These operations are atomic and useful for counters, view counts, or other numeric tracking.
// Increment a field by 1
const result = await client
.patch('post-123')
.inc({views: 1})
.commit()
// Increment multiple fields by different amounts
const bulkInc = await client
.patch('post-123')
.inc({views: 10, likes: 5})
.commit()
// Decrement a field
const decremented = await client
.patch('post-123')
.dec({stock: 1})
.commit()Conditional patches with .ifRevisionId()
The ifRevisionId() method ensures that a patch only applies if the document's current revision matches the specified revision ID. This prevents race conditions and ensures you're updating the version of the document you expect.