Joint session with Vercel: How to build intelligent storefronts (May 15th)

How to get previous and next items of same type with GROQ?

14 repliesLast updated: Nov 29, 2025

How can I retrieve with GROQ the previous and next item from the same type, such as a news post?
{
    "post": *[_type == "news" && slug.current == "${page.params.slug}"] [0],
    "prev": "???",
    "next": "???",
}
AI Update

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:

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.

Show original thread
14 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.

Related contributions