Content Model for Storing Time Data - e.g. Opening Times
For storing time-only data like store hours, you have several good options in Sanity:
Simple Approach: String Field with Predefined Options
The most straightforward way is to use a string field with a list of predefined time options:
// timeValue.ts
import {defineType} from 'sanity'
export const timeValueType = defineType({
name: 'timeValue',
title: 'Time',
type: 'string',
options: {
list: ALLOWED_TIMES(),
},
})
function ALLOWED_TIMES() {
const times = []
for (let h = 0; h < 24; h++) {
for (let m = 0; m < 60; m += 30) {
times.push(`${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}`)
}
}
return times
}Structured Approach: Object with Start/End Times
For store hours, you'll likely want a start and end time. Create an object type:
// storeHours.ts
import {defineField, defineType} from 'sanity'
export const storeHoursType = defineType({
name: 'storeHours',
title: 'Store Hours',
type: 'object',
fields: [
defineField({
name: 'day',
title: 'Day of Week',
type: 'string',
options: {
list: [
{title: 'Monday', value: 'monday'},
{title: 'Tuesday', value: 'tuesday'},
{title: 'Wednesday', value: 'wednesday'},
{title: 'Thursday', value: 'thursday'},
{title: 'Friday', value: 'friday'},
{title: 'Saturday', value: 'saturday'},
{title: 'Sunday', value: 'sunday'},
]
}
}),
defineField({
name: 'open',
title: 'Opening Time',
type: 'timeValue',
}),
defineField({
name: 'close',
title: 'Closing Time',
type: 'timeValue',
}),
],
options: {columns: 3}
})In Your Document
Then use it in an array to define hours for multiple days:
defineField({
name: 'hours',
title: 'Store Hours',
type: 'array',
of: [{type: 'storeHours'}]
})This gives you a clean structure like:
- Monday: 8:00am - 8:00pm
- Friday: 8:00am - 10:00pm
- Sunday: 8:00am - 6:00pm
Alternative: Custom Input Component
If you want more control over the editing experience, you can create a custom input component with features like:
- Reset buttons for default values
- Validation to ensure closing time is after opening time
- Visual duration display between times
The string-with-options approach is the simplest and works great for most use cases. The custom input component is worth the extra effort if you need advanced UX features for your content editors.
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.