How to preserve custom order in array of references in Sanity schema?
Great question! When you have an array of references in Sanity, the order is actually preserved by the array itself through the _key property that each item has. The issue you're seeing where items appear ordered by _id is likely happening in your GROQ query, not in the stored data.
The solution: Use the correct GROQ syntax
When you dereference an array of references, you need to use []-> to maintain the array order:
*[_id == "your-settings-id"]{
featuredProjects[]->{
_id,
title,
// other fields
}
}The []-> syntax tells GROQ to:
- Iterate through the array in its stored order
- Dereference each item
- Return them in the same order
Preserving the _key while dereferencing
If you also need access to the _key property (which determines the order), you can use this pattern:
*[_id == "your-settings-id"]{
featuredProjects[]{
_key,
...(@->)
}
}This keeps the _key from the reference object and spreads all properties from the dereferenced document.
The underlying structure
Your array of references in Sanity looks like this internally:
{
"featuredProjects": [
{
"_key": "abc123",
"_type": "reference",
"_ref": "project-id-1"
},
{
"_key": "def456",
"_type": "reference",
"_ref": "project-id-2"
}
]
}The _key property is automatically generated and maintains the order. When you reorder items in the Studio array input, Sanity preserves this order through the array structure itself—you don't need to add a custom index field.
Filtering out drafts
One bonus tip: if you want to exclude draft documents from your query results, add this filter:
*[_id == "your-settings-id" && !(_id in path("drafts.*"))]{
featuredProjects[]->{
// fields
}
}The order you set in the Studio will be maintained in your query results without any additional order() function needed!
Show original thread6 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.