
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeYou can retrieve previous and next items in GROQ by using comparison operators with ordering. Here's how to structure your query:
{
"post": *[_type == "news" && slug.current == $slug][0],
"prev": *[_type == "news" && _createdAt < *[_type == "news" && slug.current == $slug][0]._createdAt] | order(_createdAt desc)[0],
"next": *[_type == "news" && _createdAt > *[_type == "news" && slug.current == $slug][0]._createdAt] | order(_createdAt asc)[0]
}However, this approach queries the current post multiple times, which isn't efficient. A better pattern is to use a projection to avoid redundant queries:
*[_type == "news" && slug.current == $slug][0] {
...,
"prev": *[_type == "news" && _createdAt < ^._createdAt] | order(_createdAt desc)[0],
"next": *[_type == "news" && _createdAt > ^._createdAt] | order(_createdAt asc)[0]
}The ^ operator references the parent scope (the current post), so you can compare against its _createdAt field without re-querying.
Key points:
< to get items before the current one, then order(_createdAt desc)[0] to get the most recent previous item> to get items after the current one, then order(_createdAt asc)[0] to get the next item_createdAt with whatever field you want to use for ordering (like publishedAt, orderRank, etc.)^ operator helps you reference the parent document's fields within projectionsIf you're ordering by a custom field like publishedAt or want to handle published vs draft documents, adjust the filter accordingly:
*[_type == "news" && slug.current == $slug && !(_id in path("drafts.**"))][0] {
...,
"prev": *[_type == "news" && !(_id in path("drafts.**")) && publishedAt < ^.publishedAt] | order(publishedAt desc)[0],
"next": *[_type == "news" && !(_id in path("drafts.**")) && publishedAt > ^.publishedAt] | order(publishedAt asc)[0]
}This pattern works well for pagination-style navigation through content of the same type. Just make sure the field you're ordering by is indexed properly for better query performance.
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.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store