How to preserve custom order in array of references in Sanity schema?

6 replies
Last updated: Nov 29, 2025
I have a quick question on sorting. I have a Featured Projects settings of my portfolio. I setup the schema to have the Project Settings Schema be an array of references to Projects. However, when listed it orders them by _id (I know this from referencing the v3 docs) even when I change the order if projects in the array. Is there a way to add a custom index value to each reference in the array when adding it? I could then to the order() function to order by that?
AI Update

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:

  1. Iterate through the array in its stored order
  2. Dereference each item
  3. 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 thread
6 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.

Was this answer helpful?