Previous and Next Post using Next.js

Previous and Next Post using Next.js

Read 1407 times

#javascript

#nextjs

#pagination

I spent weeks trying to figure this out, I am not going to make you go through the same. Let’s get straight into it…

The Problem

On a Next.js site with posts fetched via graphql, how would you implement Previous and Next POST. This would be on the detail view of a post.

The Solution

The solution below uses graphql and Contentful but can be modified to wherever you want to apply it.

const ARTICLE_QUERY = `
query {
    articleCollection(order: publishedAt_DESC) {
      items {
        slug
        title
        excerpt
        category {
          title
          categorySlug
        }
        series {
          title
          slug
        }
        body {
          json
        }
      }
    }
  }
  
`;
async function fetchGraphQL(query) {
  return fetch(
    `https://graphql.contentful.com/content/v1/spaces/${process.env.SPACE_ID}`,
    {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: `Bearer ${process.env.CDA_TOKEN}`,
      },
      body: JSON.stringify({ query }),
    }
  )
    .then((response) => response.json())
    .catch((error) => console.error(error));
}

export async function getPostAndMorePosts(slug) {
  const response = await fetchGraphQL(ARTICLE_QUERY);
  const posts = response.data.articleCollection.items;

  const currentPost = posts.find((post) => post.slug === slug);
  const currentPostIndex = posts.findIndex((post) => post.slug === slug);
  const prevPost = posts[currentPostIndex - 1] || posts[posts.length - 1];
  const nextPost = posts[currentPostIndex + 1] || posts[0];

  if (!currentPost) {
    return {
      post: false,
    };
  }

  return {
    post: currentPost,
    morePosts: [prevPost, nextPost],
  };
}

In the code above:

in [slug].js:

import getPostAndMorePosts from '../../lib/api'

export async function getStaticPaths() {
  ...
}

export async function getStaticProps({ params }) {
  const data = await getPostAndMorePosts(params.slug);

  return {
    props: {
      post: data?.post ?? null,
      morePosts: data?.morePosts ?? null,
    },
  };
}

export default function Post({ post, morePosts }) {
	...
}

In our dynamic page:

Here is the repo with the full implementation: https://github.com/stefanjudis/jamstack-workshop/blob/main/lib/api.js


Conclusion

Thank you whitep4nth3r, Thank you to everyone who tried to help.

The full story of how we got here is coming in another article. It really puzzles me how there isn’t a native solution for this. Gatsby has it, WordPress does as well. What happened here Next.js?


Thank you for reading, let’s connect!

Thank you for visiting this little corner of mine. Let’s connect on Twitter, Polywork and LinkedIn)

Back to articles