Best route for year entry in a document and handling height as input.

15 replies
Last updated: Dec 1, 2022
What would be the best route if I wanted an input in my document to be a year entry? Are there any helpers in Sanity for this? I tried searching
"year"
on the website and it isn't helpful when "year" is returning "learn" and "search" 😅 basically I want someone to be able to select a year from a dropdown or write a year in. However, I don't want to have to keep adding years and allowing just a string input seems dangerous in the sense that they could not enter a year
AI Update

For a year input field in Sanity, you have a couple of solid options depending on your needs:

Use a number field with validation rules to constrain the input to valid years:

defineField({
  name: 'year',
  title: 'Year',
  type: 'number',
  validation: (Rule) => Rule.required().min(1900).max(2100).integer()
})

This gives you:

  • Clean numeric data storage
  • Built-in validation to prevent invalid entries
  • Simple input field that's familiar to users
  • The .integer() rule ensures no decimal values

You can adjust the min and max values to suit your needs. For example, if you only need recent years, you could set min(2000) and max(new Date().getFullYear() + 10).

Option 2: String field with a predefined list (dropdown)

If you want a dropdown with specific years, use a string field with an options.list:

defineField({
  name: 'year',
  title: 'Year',
  type: 'string',
  options: {
    list: [
      { title: '2025', value: '2025' },
      { title: '2024', value: '2024' },
      { title: '2023', value: '2023' },
      // ... more years
    ]
  }
})

The downside is you need to manually maintain the list. You could generate it programmatically in your schema:

const currentYear = new Date().getFullYear();
const years = Array.from({ length: 50 }, (_, i) => {
  const year = (currentYear - i).toString();
  return { title: year, value: year };
});

defineField({
  name: 'year',
  title: 'Year',
  type: 'string',
  options: { list: years }
})

Option 3: Date field (if you need full dates)

If you might eventually need more than just the year, you could use a date or datetime field and format it to show only the year in your frontend. However, this requires users to select a full date (like January 1st of that year), which might be awkward if you truly only care about the year.

My recommendation: Go with Option 1 (number field with validation) for the best balance of simplicity, data integrity, and user experience. It prevents invalid entries without requiring you to maintain a list of years that grows every January!

I think you’re wanting to have a drop down where users can select a year, upto and including the current year?
Correct and maybe even a future year
const lastTwentyYears = () => {
  const currentYear = new Date().getFullYear()

  let years = []
  for (var i = 0; i < 20; i++) {
    years.push((currentYear - i).toString())
  }

  return years.reverse()
}
This function would generate a list of the last 20 years (totally customizable to any number of years)
{
      type: "string",
      name: "year",
      title: "Year",
      options: {
        list: lastTwentyYears()
      }
    }
This field would use that list of years as options, creating a select item of the last 20 years
const yearsList = () => {
  const currentYear = new Date().getFullYear() + 20

  let years = []
  for (var i = 0; i < 40; i++) {
    years.push((currentYear - i).toString())
  }

  return years.reverse()
}
This example shows the last 20 years and the next 20 years
Ah that would work! I just need like to the last 5-6 and the next 5-6
I am making a dropdown for college recruiting class year so don't need to go that far
const yearsList = (future, past) => {
  const currentYear = new Date().getFullYear() + future

  let years = []
  for (var i = 0; i < (future + past); i++) {
    years.push((currentYear - i).toString())
  }

  return years.reverse()
}
Then you could call it as
yearsList(5, 5)
(5 years future, 5 years past)
Although “past” contains the current year, so it’s 10 years in total for this example
to ensure they select a year, you can add a validation rule,
validation: Rule => Rule.required()
Awesome! Thank you
Ok while I have you here, how would you handle a person's height as an input? A string or number 😅

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.

Was this answer helpful?