Ken Jones Pizza
Designer who spends most of his time coding
AI-powered automatic tagging for Sanity blog posts that analyzes content to generate 3 relevant tags, maintaining consistency by reusing existing tags from your content library.
defineField({
name: 'tags',
title: 'Tags',
type: 'array',
of: [{ type: 'string' }],
description: 'Tags will be automatically generated when you publish a post',
}),import {createClient} from '@sanity/client'
import {documentEventHandler} from '@sanity/functions'
export const handler = documentEventHandler(async ({context, event}) => {
const client = createClient({
...context.clientOptions,
apiVersion: 'vX',
useCdn: false,
})
const {data} = event
const {local} = context // local is true when running locally
try {
const result = await client.agent.action.generate({
noWrite: local ? true : false, // if local is true, we don't want to write to the document, just return the result for logging
instructionParams: {
content: {
type: 'field',
path: 'body',
},
tagsUsedInOtherPosts: {
type: 'groq',
query: "array::unique(*[_type == 'post' && _id != $id && defined(tags)].tags[])",
params: {
id: data._id,
},
},
},
instruction: `Based on the $content, create 3 relevant tags. Attempt to use $tagsUsedInOtherPosts first if they fit the context. Tags should be simple lowercase words strings and no brackets.`,
target: {
path: 'tags',
},
documentId: data._id,
schemaId: '_.schemas.default',
forcePublishedWrite: true,
})
console.log(
local ? 'Generated tags (LOCAL TEST MODE - Content Lake not updated):' : 'Generated tags:',
result.tags,
)
} catch (error) {
console.error('Error occurred during tag generation:', error)
}
})
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'
export default defineBlueprint({
resources: [
defineDocumentFunction({
type: 'sanity.function.document',
name: 'auto-tag',
src: './functions/auto-tag',
memory: 2,
timeout: 30,
event: {
on: ['create', 'update'],
filter:
"_type == 'post' && (delta::changedAny(content) || (delta::operation() == 'create' && defined(content)))",
projection: '{_id}',
},
}),
],
})This Sanity Function solves a common content management challenge: the time-consuming task of manually tagging blog posts. Content creators typically spend 2-3 minutes per post adding tags, which can lead to inconsistent tagging across your content library and reduced productivity in editorial workflows.
Quick Start
View the complete example and source code.
Initialize blueprints if you haven't already: npx sanity blueprints init
Then: npx sanity blueprints add function --example auto-tag
Then deploy: npx sanity blueprints deploy
How It Works
When a content editor publishes a new blog post without tags, the function automatically:
Key Benefits
Technical Implementation
The function uses Sanity's AI capabilities to analyze the portable text content and generate contextually relevant tags. It's built with:
Perfect For
The function is compatible with any of Sanity's official "clean" templates and can be easily customized to adjust tag count, format, or target different document types.
Designer who spends most of his time coding
Knut is a principal developer marketing manager at Sanity.io
Automatically track when content was first published with a timestamp that sets once and never overwrites, providing reliable publication history for analytics and editorial workflows.
Go to First Published Timestamp FunctionOn document publish, send a Slack notification so your team is informed
Go to Notify your team via Slack on publishCreate, preview, and send Klaviyo campaigns without ever leaving Sanity Studio"
Go to Klaviyo campaigns without leaving your StudioWrite once in Studio. Post everywhere. No copy-paste, no platform hopping.
Go to Publish Once, Post Everywhere