Gatsby Pagination with gatsby-awesome-pagination

By shane
Fri, 2019-10-04 19:35
comments
Daily Dose of Drupal Episode #10

Share with Others

In this episode, you will learn how to create pages for your content lists in Gatsby. You will learn about the gatsby-awesome-pagination plugin and how it can be installed and configured on your Gatsby site to create pages of content. You will also learn how to break your pager off into a separate reusable component so it can be added in multiple places throughout your Gatsby site.

You will need to download the gatsby-awesome-pagination plugin. Make sure to open up the command line and get to the root of your Gatsby site. Depending on if you are using npm or yarn, the command will look something like this.

yarn add gatsby-awesome-pagination

Or:

npm install --save gatsby-awesome-pagination

Open up your gatsby-node.js file and add this line of code (most likely underneath where you create the path constant.

const { paginate } = require('gatsby-awesome-pagination');

You will a GraphQL query that pulls in a list of items you want to paginate. In this case, I have a GraphQL query that pulls in article content from a Drupal site. You can view the previous lessons on how to create that, but any source that allows you to pull in a list of content can work. Once you have a GraphQL query that will create a list of items for you, you can add this to your gatsby-node.js file after your GraphQL query.

paginate({
    createPage,
    items: articles.data.allNodeArticle.nodes,
    itemsPerPage: 5,
    pathPrefix: '/blog',
    component: path.resolve(`src/templates/blog.js`),
  });

It’s important to note that items is your list of items you want to paginate, itemsPerPage is the amount of items you want on each page, pathPrefix is the path you want this listing page to be accessible at, and the component is the page component you want to use to display your listing page.

You will now need to create your page component template. Create the blog.js file in the src/templates folder. Your template may be different if you haven’t followed along with previous lessons, but here is the entire template for reference (you can modify it to fit your needs):

import React from "react";
import PropTypes from 'prop-types';
import { graphql } from 'gatsby';
 
import Layout from "../components/layout";
import SEO from "../components/seo";
import ArticlePreview from "../components/articlePreview";
import Pager from "../components/pager";
 
const Blog = ({ data, pageContext }) => {
  const articles = data.allNodeArticle.nodes;
 
  return (
    <Layout>
      <SEO title="Blog Posts" />
      <h1>Blog Posts</h1>
      {articles.map(article => (
        <ArticlePreview
          key={article.id}
          title={article.title}
          path={article.path.alias}
          image={article.relationships.field_image.localFile.childImageSharp.fluid}
          alt={article.field_image.alt}
          summary={article.body.summary ? article.body.summary : article.body.processed.substring(0, 300)}
        />
      ))}
      <Pager pageContext={pageContext} />
    </Layout>
  );
};
 
Blog.propTypes = {
  data: PropTypes.object.isRequired,
  pageContext: PropTypes.object.isRequired,
};
 
export const query = graphql`
  query ($skip: Int!, $limit: Int!) {
    allNodeArticle(
      sort: {fields: created, order: DESC}
      skip: $skip
      limit: $limit
    ) {
      nodes {
        id
        title
        created
        body {
          processed
          summary
        }
        path {
          alias
        }
        field_image {
          alt
        }
        relationships {
          field_image {
            localFile {
              childImageSharp {
                fluid(maxWidth: 600) {
                  ...GatsbyImageSharpFluid
                }
              }
            }
          }
        }
      }
    }
  }
`;
 
export default Blog;

There are a few important things to note about this template. First I created a component to display my ArticlePreview and a component for my Pager (which we will look at next). The Pager component requires pageContext which is pulled in through a prop in line 10.

In the GraphQL query, you will notice the skip and limit variables. This is how the gatsby-awesome-paginate plugin controls what items show up on each page. The paginate function we called will run this template and query once for each page and only pull the items that should be displayed on this page. The rest of the template should look relatively familiar if you have been working with other templates in the past.

The Pager component is where the pager actually gets created. I didn’t do much to style the component, but once you see how to display the pagers you can style them as you see fit.

import { Link } from "gatsby";
import PropTypes from "prop-types";
import React from "react";
 
const Pager = ({ pageContext }) => {
  const { previousPagePath, nextPagePath } = pageContext;
 
  return (
    <div>
      {previousPagePath && (
        <span><Link to={previousPagePath}>Previous</Link></span>
      )}
      {nextPagePath && (
        <span><Link to={nextPagePath}>Next</Link></span>
      )}
    </div>
  );
};
 
Pager.propTypes = {
  pageContext: PropTypes.object.isRequired,
};
 
export default Pager;

That’s really all there is to get basic pager functionality working in Gatsby. Once you have the basics working you can modify this to fit the needs of any pagination on your site and by using a separate Pager component, you can style the pager once and add it to any list that requires paging functionality.