Is it possible to generate a field value of a document every time it is edited in Sanity.io?
For your use case of automatically updating a path field whenever a document or its nested categories change, you have a few solid options. Let me walk through the most practical approaches:
Option 1: Custom Input Component (Client-Side)
You can create a custom input component that listens to changes in your document and automatically updates the path field. This uses useFormValue to watch for changes:
import { useFormValue } from 'sanity'
import { useEffect } from 'react'
import { set, unset } from 'sanity'
export function PathInput(props) {
const { onChange, value } = props
const categories = useFormValue(['categories'])
useEffect(() => {
if (categories) {
const generatedPath = generatePathFromCategories(categories)
if (generatedPath !== value) {
onChange(generatedPath ? set(generatedPath) : unset())
}
}
}, [categories, value, onChange])
return (
<div>
<input type="text" value={value || ''} readOnly />
</div>
)
}Then in your schema:
{
name: 'path',
type: 'string',
components: {
input: PathInput
}
}Pros: Runs in real-time as users edit, no server-side setup needed
Cons: Only works when the document itself is open in Studio; won't update if a referenced category changes
Option 2: Sanity Functions (Server-Side, Recommended)
Sanity Functions can automatically update fields when documents are published. This is the modern, recommended approach for reacting to content changes. Note that Functions are currently an experimental feature.
First, initialize blueprints in your project:
npx sanity blueprints init
npx sanity blueprints add function --name update-pathThen configure your function in sanity.blueprint.ts:
import { defineBlueprint, defineDocumentFunction } from '@sanity/blueprints'
export default defineBlueprint({
resources: [
defineDocumentFunction({
type: 'sanity.function.document',
name: 'update-path',
src: './functions/update-path',
event: {
on: ['create', 'update'],
filter: '_type == "yourDocumentType"',
},
}),
],
})And implement the handler in ./functions/update-path/index.ts:
import type { SanityDocumentEventHandler } from '@sanity/blueprints'
export const handler: SanityDocumentEventHandler = async ({ document, client }) => {
const newPath = generatePathFromCategories(document.categories)
// Prevent infinite loops - only update if path changed
if (document.path !== newPath) {
await client.patch(document._id).set({ path: newPath }).commit()
}
}Deploy with:
npx sanity blueprints deployPros: Runs server-side, can react to changes in referenced documents if you set up additional function triggers
Cons: Experimental feature (APIs may change), requires Growth plan or higher, more complex setup
Important: As noted in the Functions documentation, Functions don't currently prevent recursive loops automatically, so make sure to check if the path actually changed before patching the document.
Option 3: Custom Document Action
You can create a custom document action using the useDocumentOperation hook that computes the path when users click "Publish". This gives you control over when the computation happens but requires user interaction.
import { useDocumentOperation } from 'sanity'
export function PublishWithPathAction(props) {
const { patch, publish } = useDocumentOperation(props.id, props.type)
return {
label: 'Publish',
onHandle: () => {
const newPath = generatePathFromCategories(props.draft.categories)
patch.execute([{ set: { path: newPath } }])
publish.execute()
props.onComplete()
}
}
}Recommendation
If you need the path to update when referenced category documents change (not just when the main document changes), Sanity Functions are your best bet despite being experimental. If you only need updates when the document itself is edited and users will have it open in Studio, the custom input component approach is simpler and doesn't require server-side infrastructure.
For the custom input approach, you can also use useFormValue to access referenced document data if you need to generate paths based on the full category structure, not just the references themselves.
Sanity – Build the way you think, not the way your CMS thinks
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.