
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storePage description goes here
import {defineField, defineType} from 'sanity'
export const heroType = defineType({
name: 'hero',
title: 'Hero',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'description',
title: 'Description',
type: 'text',
rows: 3,
}),
defineField({
name: 'image',
title: 'Image',
type: 'image',
options: {
hotspot: true,
},
fields: [
{
name: 'alt',
type: 'string',
title: 'Alternative text',
description: 'Important for SEO and accessibility.',
},
],
}),
],
preview: {
select: {
title: 'title',
subtitle: 'description',
media: 'image',
},
},
})npx create sanity@latest npx sanity typegen generate ✓ Config loaded from ./sanity.cli.ts ✔ Schema loaded from ./node_modules/@repo/sanity-extracted-schema/schema.json ✔ Successfully generated types to /Users/knut/Sites/sanity-io/www-sanity-io/apps/studio/sanity.types.ts in 7827ms └─ 1 query and 603 schema types └─ found queries in 1 file after evaluating 229 files └─ formatted the generated code with prettier npx sanity dev ✓ Checking configuration files... ✓ Starting dev server Sanity Studio using vite@7.3.1 ready in 687ms and running at http://localhost:3333/
Agent actions, functions, and content agents automate manual work before and after hitting publish.

@Jason published a new product: ST07 Winter Jacket
import {documentEventHandler} from '@sanity/functions'
import {createClient} from '@sanity/client'
const STOREFRONT_WEBHOOK = process.env.STOREFRONT_WEBHOOK_URL
export const handler = documentEventHandler(async ({context, event}) => {
const {data} = event
if (!STOREFRONT_WEBHOOK) {
console.error('❌ STOREFRONT_WEBHOOK_URL not found in environment variables')
return
}
const client = createClient({
...context.clientOptions,
apiVersion: '2025-06-01',
})
// Find every document that references the published product
const referencing = await client.fetch(
`*[references($id)]{
_id,
_type,
title,
"slug": slug.current
}`,
{id: data._id},
)
if (!referencing.length) {
console.log(`📭 No references found for ${data._id}`)
return
}
console.log(`🔗 Found ${referencing.length} documents referencing ${data._id}`)
// Notify the storefront so it can rebuild affected pages
try {
const response = await fetch(STOREFRONT_WEBHOOK, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
event: 'product.updated',
productId: data._id,
affectedPages: referencing.map((doc) => ({
id: doc._id,
type: doc._type,
slug: doc.slug,
})),
}),
})
if (!response.ok) {
throw new Error(`Webhook returned ${response.status}`)
}
console.log(`✅ Storefront notified about ${referencing.length} affected pages`)
} catch (error) {
console.error('❌ Failed to notify storefront:', error)
throw error
}
})import {documentEventHandler} from '@sanity/functions'
import {createClient} from '@sanity/client'
const STOREFRONT_WEBHOOK = process.env.STOREFRONT_WEBHOOK_URL
export const handler = documentEventHandler(async ({context, event}) => {
const {data} = event
if (!STOREFRONT_WEBHOOK) {
console.error('❌ STOREFRONT_WEBHOOK_URL not found in environment variables')
return
}
const client = createClient({
...context.clientOptions,
apiVersion: '2025-06-01',
})
// Find every document that references the published product
const referencing = await client.fetch(
`*[references($id)]{
_id,
_type,
title,
"slug": slug.current
}`,
{id: data._id},
)
if (!referencing.length) {
console.log(`📭 No references found for ${data._id}`)
return
}
console.log(`🔗 Found ${referencing.length} documents referencing ${data._id}`)
// Notify the storefront so it can rebuild affected pages
try {
const response = await fetch(STOREFRONT_WEBHOOK, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
event: 'product.updated',
productId: data._id,
affectedPages: referencing.map((doc) => ({
id: doc._id,
type: doc._type,
slug: doc.slug,
})),
}),
})
if (!response.ok) {
throw new Error(`Webhook returned ${response.status}`)
}
console.log(`✅ Storefront notified about ${referencing.length} affected pages`)
} catch (error) {
console.error('❌ Failed to notify storefront:', error)
throw error
}
})Turn your content into a governed knowledge layer that powers applications and AI agents.
Store any valid JSON document, with schemas living in your Sanity Studio configuration, not as database constraints.




Enable creative freedom with infinitely customizable workflows.




The first content agent that knows your content, so you can action with accuracy at scale.




Automate content operations, from AI enrichment to syncing with any system, triggered by any mutation in your dataset.




Now, with Sanity you can power not only web and content applications but your own agents. Structured data that powers intelligence.
























0
0 custom APIs
300%
Faster release cycles
90%
of updates owned by the content team
5x
faster dev velocity
144x
faster product launches
10k
products updated in 30 seconds
80
hours saved per month
60
lines of code
Zero
added services
“Lady Gaga’s team had never used a CMS before. Now they are logging into Sanity and using Sanity Studio to make updates on their own.”
Melody YungCreative Lead & Founder
“I want to build tools and systems that, at no point, should I have to say 'no, I can't do that' it's more 'should we do that?' And if the answer is yes, then we have the stack and the ability to go and do it”
Kevin HarwoodCTO
“We have a marketplace and partner with a lot of brands — commerce is definitely the next big initiative for us. We're essentially becoming multiple companies at once.”
Anthony RiveraDirector of Engineering at Complex
Model, manage, automate, and scale structured content across all your brands, apps, and touch points.
SOC 2 Type II
GDPR
CCPA
Install Sanity and create a new project directly from your terminal.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeimport {defineField, defineType} from 'sanity'
export const heroType = defineType({
name: 'hero',
title: 'Hero',
type: 'document',
fields: [
defineField({
name: 'title',
title: 'Title',
type: 'string',
validation: (Rule) => Rule.required(),
}),
defineField({
name: 'description',
title: 'Description',
type: 'text',
rows: 3,
}),
defineField({
name: 'image',
title: 'Image',
type: 'image',
options: {
hotspot: true,
},
fields: [
{
name: 'alt',
type: 'string',
title: 'Alternative text',
description: 'Important for SEO and accessibility.',
},
],
}),
],
preview: {
select: {
title: 'title',
subtitle: 'description',
media: 'image',
},
},
})npx create sanity@latest
npx sanity typegen generate
✓ Config loaded from ./sanity.cli.ts
✔ Schema loaded from ./node_modules/@repo/sanity-extracted-schema/schema.json
✔ Successfully generated types to /Users/knut/Sites/sanity-io/www-sanity-io/apps/studio/sanity.types.ts in 7827ms
└─ 1 query and 603 schema types
└─ found queries in 1 file after evaluating 229 files
└─ formatted the generated code with prettier
npx sanity dev
✓ Checking configuration files...
✓ Starting dev server
Sanity Studio using vite@7.3.1 ready in 687ms
and running at http://localhost:3333/import {documentEventHandler} from '@sanity/functions'
import {createClient} from '@sanity/client'
const STOREFRONT_WEBHOOK = process.env.STOREFRONT_WEBHOOK_URL
export const handler = documentEventHandler(async ({context, event}) => {
const {data} = event
if (!STOREFRONT_WEBHOOK) {
console.error('❌ STOREFRONT_WEBHOOK_URL not found in environment variables')
return
}
const client = createClient({
...context.clientOptions,
apiVersion: '2025-06-01',
})
// Find every document that references the published product
const referencing = await client.fetch(
`*[references($id)]{
_id,
_type,
title,
"slug": slug.current
}`,
{id: data._id},
)
if (!referencing.length) {
console.log(`📭 No references found for ${data._id}`)
return
}
console.log(`🔗 Found ${referencing.length} documents referencing ${data._id}`)
// Notify the storefront so it can rebuild affected pages
try {
const response = await fetch(STOREFRONT_WEBHOOK, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
event: 'product.updated',
productId: data._id,
affectedPages: referencing.map((doc) => ({
id: doc._id,
type: doc._type,
slug: doc.slug,
})),
}),
})
if (!response.ok) {
throw new Error(`Webhook returned ${response.status}`)
}
console.log(`✅ Storefront notified about ${referencing.length} affected pages`)
} catch (error) {
console.error('❌ Failed to notify storefront:', error)
throw error
}
})import {documentEventHandler} from '@sanity/functions'
import {createClient} from '@sanity/client'
const STOREFRONT_WEBHOOK = process.env.STOREFRONT_WEBHOOK_URL
export const handler = documentEventHandler(async ({context, event}) => {
const {data} = event
if (!STOREFRONT_WEBHOOK) {
console.error('❌ STOREFRONT_WEBHOOK_URL not found in environment variables')
return
}
const client = createClient({
...context.clientOptions,
apiVersion: '2025-06-01',
})
// Find every document that references the published product
const referencing = await client.fetch(
`*[references($id)]{
_id,
_type,
title,
"slug": slug.current
}`,
{id: data._id},
)
if (!referencing.length) {
console.log(`📭 No references found for ${data._id}`)
return
}
console.log(`🔗 Found ${referencing.length} documents referencing ${data._id}`)
// Notify the storefront so it can rebuild affected pages
try {
const response = await fetch(STOREFRONT_WEBHOOK, {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
event: 'product.updated',
productId: data._id,
affectedPages: referencing.map((doc) => ({
id: doc._id,
type: doc._type,
slug: doc.slug,
})),
}),
})
if (!response.ok) {
throw new Error(`Webhook returned ${response.status}`)
}
console.log(`✅ Storefront notified about ${referencing.length} affected pages`)
} catch (error) {
console.error('❌ Failed to notify storefront:', error)
throw error
}
})