Validate updatedAt is greater than publishedAt in Sanity schema
Yes, you can absolutely validate that updatedAt is greater than publishedAt using Sanity's custom validation! Here's how to do it:
defineField({
name: 'updatedAt',
type: 'datetime',
validation: (rule) =>
rule.custom((updatedAt, context) => {
const publishedAt = context.document?.publishedAt;
if (!updatedAt || !publishedAt) {
return true; // Allow if either field is empty
}
const updatedDate = new Date(updatedAt);
const publishedDate = new Date(publishedAt);
if (updatedDate < publishedDate) {
return 'Updated date cannot be earlier than published date';
}
return true;
}),
})The key here is using Rule.custom() with the context parameter, which gives you access to context.document containing all fields in the current document. This lets you compare the two datetime fields.
You can also add the same validation to your publishedAt field to catch the issue from either direction:
defineField({
name: 'publishedAt',
type: 'datetime',
validation: (rule) =>
rule.custom((publishedAt, context) => {
const updatedAt = context.document?.updatedAt;
if (!publishedAt || !updatedAt) {
return true;
}
if (new Date(publishedAt) > new Date(updatedAt)) {
return 'Published date cannot be later than updated date';
}
return true;
}),
})As for the built-in _createdAt and _updatedAt system fields - yeah, I hear your frustration! Those are managed automatically by Sanity but they track document creation/modification in the Content Lake, not publication dates. For editorial workflows where you need to control when content appears to be "published" or "updated" from a user perspective, custom fields like yours are the standard approach. The validation system at least makes it straightforward to enforce the business logic you need.
You can find more details about custom validation in the Sanity validation documentation and this guide on adding custom validation rules.
Show original thread10 replies
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.