Retrieving previous and next items with GROQ in Sanity.io
14 replies
Last updated: Jun 3, 2021
F
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": "???", }
Jun 2, 2021, 1:53 PM
F
It is indeed having a date field
Jun 2, 2021, 2:01 PM
G
I would start with something like this to see if it works for you. You can change
_createdAtto whichever date field you want (ideally a dateTime, and it will need to be unique). Remove
_idafter the filters if you want to return the whole object.
*[_type == 'news' && slug.current == "${page.params.slug}"][0] { ..., 'prev': *[_type == 'news' && !(_id in path('drafts.**')) && _createdAt < ^._createdAt]._id | order(_createdAt desc)[0], 'next': *[_type == 'news' && !(_id in path('drafts.**')) && _createdAt > ^._createdAt]._id | order(_createdAt desc)[0] }
Jun 2, 2021, 2:30 PM
G
I would start with something like this to see if it works for you. You can change
_createdAtto whichever date field you want (ideally a dateTime, and it will need to be unique). Remove
_idafter the filters if you want to return the whole object.
*[_type == 'news' && slug.current == "${page.params.slug}"][0] { ..., 'prev': *[_type == 'news' && !(_id in path('drafts.**')) && _createdAt < ^._createdAt]._id | order(_createdAt desc)[0], 'next': *[_type == 'news' && !(_id in path('drafts.**')) && _createdAt > ^._createdAt]._id | order(_createdAt desc)[0] }
Jun 2, 2021, 2:30 PM
F
user A
seems to work pretty well! You're a true genius haha, thanksJun 2, 2021, 2:43 PM
G
Glad it works for you! 🙌
Jun 2, 2021, 2:56 PM
G
Glad it works for you! 🙌
Jun 2, 2021, 2:56 PM
F
Alright
user A
, spoke too soon haha. So it does work, but let's say I'm on the post 3 (the oldest from the date field) and want to go to the previous one, it jumps to the first post in date and not the one just before the current one in date if that makes sense*[_type == "news" && slug.current == "${page.params.slug}"] [0] { ..., "next": *[_type == 'news' && !(_id in path('drafts.**')) && date > ^.date] | order(date desc) [0], "prev": *[_type == 'news' && !(_id in path('drafts.**')) && date < ^.date] | order(date desc) [0] }
Jun 3, 2021, 8:41 AM
F
I believe it's because it's taking the first with [0] on
prev, but I have no clue how to get the one just before 🤔
Jun 3, 2021, 8:44 AM
G
Just to make sure we’re using the same terms, what do you mean by “the previous one?” If you’re on post 3, and it’s the oldest post, I would expect
prevto be null.
Jun 3, 2021, 2:22 PM
F
By previous I mean the one just before according to the date
Jun 3, 2021, 2:38 PM
F
By previous I mean the one just before according to the date
Jun 3, 2021, 2:38 PM
F
so let's say we have 2021-04-23, 2020-09-15, 2019-07-21 and I'm on 2019-07-21, I should have 2020-09-15 as my "previous" post
Jun 3, 2021, 2:39 PM
F
but right now it gets the first of all, so 2021-04-23
Jun 3, 2021, 2:39 PM
G
K, thank you. It might be a game of playing with your orders (using
ascinstead of
desc, for example).
Jun 3, 2021, 2:45 PM
Sanity– build remarkable experiences at scale
Sanity is a modern headless CMS that treats content as data to power your digital business. Free to get started, and pay-as-you-go on all plans.