examples/functions/first-published/README.md
Content teams need to track when articles were first published for analytics and editorial workflows, but manually setting timestamps is error-prone and often forgotten during publishing.
This Sanity Function automatically sets a firstPublished timestamp when a post is published for the first time, using setIfMissing to ensure the value is only set once and never overwritten.
Initialize the example
Run this if you haven't initialized blueprints:
npx sanity blueprints init
You'll be prompted to select your organization and Sanity studio.
Then run:
npx sanity blueprints add function --example first-published
Add configuration to your blueprint
// sanity.blueprint.ts
defineDocumentFunction({
name: 'first-published',
memory: 1,
timeout: 10,
event: {
on: ['create'],
filter: "_type == 'post' && !defined(firstPublished)",
projection: '{_id}',
},
})
Install dependencies
npm install
You can test the first-published function locally using the Sanity CLI before deploying.
Test the function with an existing document ID from your dataset:
npx sanity functions test first-published --document-id <insert-document-id> --dataset production --with-user-token
Replace <insert-document-id> with an actual document ID from your dataset and production with your dataset name.
Start the development server for interactive testing:
npx sanity functions dev
Add temporary logging to your function:
// Add debugging logs
console.log('Event data:', JSON.stringify(event.data, null, 2))
console.log('Setting firstPublished for:', data._id)
Once you've tested your function locally and are satisfied with its behavior, you can deploy it to production.
Important: Make sure you have the Deploy Studio permission for your Sanity project before attempting to deploy.
Verify your blueprint configuration
Make sure your sanity.blueprint.ts file is properly configured with the first-published function:
// sanity.blueprint.ts
import {defineBlueprint, defineDocumentFunction} from '@sanity/blueprints'
export default defineBlueprint({
resources: [
defineDocumentFunction({
name: 'first-published',
src: './functions/first-published',
memory: 1,
timeout: 10,
event: {
on: ['create'],
filter: "_type == 'post' && !defined(firstPublished)",
projection: '{_id}',
},
}),
],
})
Deploy your blueprint
From your project root, run:
npx sanity blueprints deploy
This command will:
Verify deployment
After deployment, you can verify your function is active by:
firstPublished field is setfirstPublished to avoid unnecessary executionsfirstPublished field exists in your schemaError: "Deploy Studio permission required"
Error: "Blueprint validation failed"
sanity.blueprint.ts configurationFunction not setting firstPublished after deployment
firstPublished set and verify the field exists in your schemaFor more details, see the official function deployment documentation.
post document type containing:
firstPublished field (datetime) for storing the timestampWhen a content editor publishes a new blog post for the first time, the function automatically:
setIfMissing to prevent overwritingResult: Content teams get automatic first-publish tracking without manual effort, enabling accurate analytics and editorial workflows.
Modify the blueprint filter to target different content types:
filter: "_type == 'article' && !defined(firstPublished)"
Update the field name being set:
await client.patch(data._id, {
setIfMissing: {
initialPublishDate: new Date().toISOString(), // Different field name
},
})
Set multiple fields when first publishing:
await client.patch(data._id, {
setIfMissing: {
firstPublished: new Date().toISOString(),
publishedYear: new Date().getFullYear(),
publishedMonth: new Date().getMonth() + 1,
},
})