Retrieving previous and next items with GROQ in Sanity.io
You 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:
- Use
<to get items before the current one, thenorder(_createdAt desc)[0]to get the most recent previous item - Use
>to get items after the current one, thenorder(_createdAt asc)[0]to get the next item - Replace
_createdAtwith whatever field you want to use for ordering (likepublishedAt,orderRank, etc.) - The
^operator helps you reference the parent document's fields within projections
If 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 – 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.