Pagination for array of references in Sanity GROQ query not working
*[_type == 'market' && siteDomain == "<http://www.website.se|www.website.se>"][0] {
'tripCollections': tripCollections[@->nameSv in ["Spain"]] -> {
'name': @.['nameSv'],
'trips': trips[_id > "trip-17058401-3baa-40cf-8fc9-11869112b117"] | order(_id) [0...3] -> {
_id,
recipe,
'images': images[]->image.asset->url,
'headline': contentSv->headline,
'salesPitch': contentSv->salesPitch,
'slug': contentSv->slug
}
}
}
trips[_id > "trip-17058401-3baa-40cf-8fc9-11869112b117"] | order(_id) [0...3]But for some reason I just get an empty result.
Is there anything obvious that I’m doing wrong?
If it wasn’t clear already,
tripsis an array. Also not sure if it matters but the order of the elements are important to me, I wish to preserve them the way they are in listed in the CMS.
Also important to note that the array is an array of references
I can see the issue with your query! When you're trying to paginate through an array of references with trips[_id > "trip-17058401-3baa-40cf-8fc9-11869112b117"], the problem is that you're filtering on _id before dereferencing with ->.
At that point in the query, trips is still an array of reference objects (like {_ref: "trip-123", _type: "reference"}), not the actual trip documents. Reference objects don't have an _id field—they have a _ref field. So your filter isn't matching anything, which is why you're getting empty results.
Here are two ways to fix this:
Option 1: Filter after dereferencing (simpler but less efficient)
*[_type == 'market' && siteDomain == "www.website.se"][0] {
'tripCollections': tripCollections[@->nameSv in ["Spain"]] -> {
'name': @.['nameSv'],
'trips': trips[]-> {
_id,
recipe,
'images': images[]->image.asset->url,
'headline': contentSv->headline,
'salesPitch': contentSv->salesPitch,
'slug': contentSv->slug
} | order(_id) [select(_id > "trip-17058401-3baa-40cf-8fc9-11869112b117")] [0...3]
}
}This dereferences all trips first, then filters and slices. However, this isn't ideal for performance since it fetches all trips before filtering.
Option 2: Use _ref for filtering (more efficient)
*[_type == 'market' && siteDomain == "www.website.se"][0] {
'tripCollections': tripCollections[@->nameSv in ["Spain"]] -> {
'name': @.['nameSv'],
'trips': trips[_ref > "trip-17058401-3baa-40cf-8fc9-11869112b117"][0...3] -> {
_id,
recipe,
'images': images[]->image.asset->url,
'headline': contentSv->headline,
'salesPitch': contentSv->salesPitch,
'slug': contentSv->slug
}
}
}This filters on _ref before dereferencing, which is more efficient.
Important note about order preservation
You mentioned that the order of elements is important and you want to preserve them as listed in the CMS. Be careful with | order(_id)—this will sort by document ID, not by the original array order!
If you want to preserve the original order from the CMS, simply remove the order(_id) part entirely. Arrays in Sanity maintain their order, so just slice without sorting:
'trips': trips[_ref > "trip-17058401-3baa-40cf-8fc9-11869112b117"][0...3] -> {
// your fields
}This way you'll get the trips in the exact order they appear in your CMS, starting from the reference after your cursor ID and taking the next 3 items.
Show original thread2 replies
Was this answer helpful?
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.