Pagination blog post category

Hi @Phil

I was about to write a new post on this after having read this thread a few days ago, but noticed there'd been activity on here since and you'd been helping someone out with their query. Hoping this is fresh in your mind and you'll have a quick and easy answer to my question.

I'm currently trying to paginate my blog category pages located at filepath: '/categories/[uid].js'.

I found the following posts that seem to offer an indication of how it might be done:

Unfortunately, I've still not managed to get anything running successfully, despite trying a few different iterations with snippets from the above posts. My getStaticProps and getStaticPaths functions look a bit different to those in the above posts which is throwing me off.

Here is the code I have so far. It would be amazing if you could offer some guidance in how to take this from where it is now to having working pagination.

Thanks

export const getStaticProps = async ({ params }) => {
  const page = await useGetStaticProps({
    client: Client(),
    type: 'blog-category',
    apiParams({ params }) {
      return {
        uid: params.uid,
      };
    },
  })({ params });

  const blogPosts = await Client().query(
    [
      Prismic.Predicates.at('document.type', 'blog-post'),
      Prismic.Predicates.at('my.blog-post.category', page.props.id),
    ],
    { orderings: '[my.blog-post.date desc]' },
  );

  return {
    props: {
      params: params,
      blogPosts: blogPosts,
      ...page.props,
    },
  };
};

export const getStaticPaths = useGetStaticPaths({
  client: Client(),
  type: 'blog-category',
  formatPath: (prismicDocument) => {
    return {
      params: {
        uid: prismicDocument.uid,
      },
    };
  },
});

Hi David,

It looks like in your code you're doing this with the next-slicezone useGetStaticProps method, it's definitely easier in my opinion to do this with @prismic/client.

I can see in your example you want to query all your blog posts on the blog category page. You can see how we do this on the homepage of our next.js blog example using @prismic/client:

Hopefully, this will help, if you have any further questions let me know.

Thanks.

Hi Phil, thanks very much for posting this, it has helped and I have something that seems to be working mostly how I want it to (caveat coming later in this post though...)

The code in this post was particularly useful, but mine ended up being a little different in the end:

I tried the do while loop, but it just returned all posts, whereas removing the loop and just fetching the posts needed for the page (as shown in my code below) seemed to work. Not sure why, or if this means I'm doing something wrong with my code.

The one issue I'm having is the page is rendering for invalid page numbers. I.e., I could go to /blog/category/category-name/300 and it the page would render, even though there aren't 300 pages. There would be no data returned from getStaticProps, but I would hope that this would return a 404 page instead of a blank page without data.

I wasn't sure if this was something I was doing wrong? (perhaps due to the do while loop). I'm new to Next (coming from Gatsby previously) so am unfamiliar with how these situations are handled, perhaps it's convention to just redirect to 404 page if no data?

For anyone who would find it useful, here are my getSaticProps and getStaticPaths methods in my /blog/category/[uid]/[page].js file

export const getStaticProps = async ({ params }) => {
  const category = (await Client().getByUID('blog-category', params.uid)) || {};

  const posts = await Client().query(
    [
      Prismic.Predicates.at('document.type', 'blog-post'),
      Prismic.Predicates.at('my.blog-post.category', category.id),
    ],
    {
      pageSize: 1,
      page: params.page,
      orderings: '[document.first_publication_date desc]',
    },
  );

  return {
    props: {
      params: params,
      posts,
      category,
    },
  };
};



export const getStaticPaths = async () => {
  const categories = await Client().query(
    Prismic.Predicates.at('document.type', 'blog-category'),
  );

  const data = [];

  for (const cat of categories.results) {
    const categoryBlogPosts = await Client().query(
      [
        Prismic.Predicates.at('document.type', 'blog-post'),
        Prismic.Predicates.at('my.blog-post.category', cat.id),
      ],
      { orderings: '[my.blog-post.date desc]', page: 1, pageSize: 1 },
    );

    data.push(
      Array.from(Array(categoryBlogPosts.total_pages).keys()).map((x) => ({
        uid: cat.uid,
        page: `${x + 1}`,
        total_pages: categoryBlogPosts.total_pages,
      })),
    );
  }

  return {
    paths: data.flat().map((doc) => ({
      params: {
        page: doc.page,
        total_pages: doc.total_pages,
        uid: doc.uid,
      },
    })),
    fallback: true,
  };
};

Hey David,

I'm glad you got this working :) Thanks for sharing your solution.

Yes, as you suggested this should the standard behviour.

Thanks.

1 Like

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.