Troubleshooting unique year values query in Next.js Sanity project.
Yes! You can extract unique years from datetime fields in GROQ. The key is to convert the datetime to a string first, then use string::split() to extract the year portion. Here's the working solution:
{
"uniqueYears": array::unique(
*[_type in ["event", "exhibition"] && defined(endDate)]
.endDate
) | [string::split(string(@), "-")[0]]
}How this works:
- The filter
*[_type in ["event", "exhibition"] && defined(endDate)]gets your documents .endDateextracts just the endDate values from each documentarray::unique()removes duplicate datetime values- The pipe operator
|passes the unique datetimes to the next operation - The projection
[...]applies a transformation to each element in the array string()function converts each datetime to a string in RFC3339 format (like"2018-01-06T12:30:00.000Z")string::split(string(@), "-")breaks the string at each"-"character, creating an array like["2018", "01", "06T12:30:00.000Z"][0]grabs just the first element (the year)
This will give you:
{
"uniqueYears": ["2018", "2019", "2020"]
}Alternative approach - You can also apply the transformation before uniquifying:
{
"uniqueYears": array::unique(
*[_type in ["event", "exhibition"] && defined(endDate)]
.[string::split(string(endDate), "-")[0]]
)
}Why your original approach didn't work:
- The
split()function needs thestring::namespace prefix in GROQ - It only works on strings, so your datetime
endDatefield needs to be converted first usingstring() - The syntax for applying transformations across arrays requires proper use of projections with
[]
The years will be returned as strings. If you need them as numbers for sorting or comparison, you'd need to handle that conversion in your application code since GROQ doesn't have a built-in string-to-number conversion function.
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.