How to Add Pagination to your Gatsby JS Website using gatsby-awesome-pagination
Written by Brian
Today, I will show you how you can add pagination to your Gatsby JS website using an awesome plugin called gatsby-awesome-pagination. You can see the original docs for this plugin here.
The first thing you will need to do is install the gatsby-awesome-pagination plugin. You can use yarn or npm to install it. I have yarn, so I will use the code below.
yarn add gatsby-awesome-pagination
Next, you will need to import paginate into your gatsby-node.js file
import { paginate } from "gatsby-awesome-pagination"
Then, you will have to add the paginate method and update the values.
The docs have a template that you can fill out, but I'll show you how I did mine, in case you were confused with the way they did it.
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const result = await graphql(`
query {
allMdx(filter: { fileAbsolutePath: { regex: "/posts/" } }) {
edges {
node {
frontmatter {
slug
}
}
}
}
}
`)
paginate({
createPage, // The Gatsby `createPage` function
items: result.data.allMdx.edges, // An array of objects
itemsPerPage: 6, // How many items you want per page
pathPrefix: "/posts", // Creates pages like `/blog`, `/blog/2`, etc
component: path.resolve("src/templates/blog.js"), // Just like `createPage()`
})
}
So, my setup is a little different from the official docs. Basically, I query the data from graphql to display all my MDX files. I have multiple folders with different types of content, but I only want to use the pagination for my posts folder.
If you only have one folder for your content, then you can ignore the filter I put. However, if you need to filter for a specific type of content, then you would want to add this code into your graphql query.
filter: {
fileAbsolutePath: {
regex: "/posts/"
}
}
Again, this is completely optional, but I couldn't find any tutorials showing that option, so I figured I'd leave that in.
So, looking at the paginate method, you simply just have to add your values into the object.
paginate({
createPage, // The Gatsby `createPage` function
items: result.data.allMdx.edges, // An array of objects
itemsPerPage: 6, // How many items you want per page
pathPrefix: "/posts", // Creates pages like `/blog`, `/blog/2`, etc
component: path.resolve("src/templates/blog.js"), // Just like `createPage()`
})
I set my items per page to only show 6 posts. The pathPrefix is what you want your URL to be when showing the pagination.
I want to display my blog post on the "/posts" URL, so I set it as "/posts" for the pathPrefix. The last value is for the component and you will need to create one (if you don't have one already) to display your post.
First, create a new file in your templates folder. I called mine blog.js.
Here is an example of my code for the blog.js file. Note, whatever you name your file is what you put for the components value in the pagination method.
Here you can see that I have my template located in my templates folder with the file name of blog.js.
component: path.resolve("src/templates/blog.js")
Next, you can add your code to the blog.js file.
const Blog = ({ data, pageContext }) => {
const {
allMdx: { nodes: posts },
} = data
return (
<Layout>
<SEO title="Posts" />
<h1 className="post__heading">Check out my Blog Post</h1>
<Posts posts={posts} key={posts.id} />
<Pager pageContext={pageContext} />
</Layout>
)
}
export default Blog
Blog.propTypes = {
data: PropTypes.object.isRequired,
pageContext: PropTypes.object.isRequired,
}
export const query = graphql`
query($skip: Int!, $limit: Int!) {
allMdx(
filter: { fileAbsolutePath: { regex: "/posts/" } }
sort: { order: DESC, fields: frontmatter___date }
skip: $skip
limit: $limit
) {
nodes {
id
frontmatter {
title
path
slug
date(formatString: "MMMM Do, YYYY")
image {
childImageSharp {
fluid {
...GatsbyImageSharpFluid
}
}
}
}
}
}
}
`
I have a separate component called Posts that maps through all my posts and displays them. You would replace that with your own component that displays your content.
<Posts posts={posts} key={posts.id} />
Then, you would just query the data from graphql. Yours will most likely look different from mine.
The final thing you need to do is create a pager.js file that will display the pagination.
I created mine in my components folder.
Here is an example of the code I used for my pager.js file. You will have to customize the CSS to fit your own design.
const Pager = ({ pageContext }) => {
const {
previousPagePath,
nextPagePath,
humanPageNumber,
numberOfPages,
} = pageContext
return (
<div className="pager">
<nav className="pager__container">
{previousPagePath ? (
<Link to={previousPagePath} className="pager__button">
<button>
<FiArrowLeft className="pager__icon--left" />
Previous Page
</button>
</Link>
) : null}
{numberOfPages > 1 && (
<div className="pager__location">
Page {humanPageNumber} of {numberOfPages}
</div>
)}
{nextPagePath && (
<Link to={nextPagePath} className="pager__button">
<button>
See More Posts
<FiArrowRight className="pager__icon--right" />
</button>
</Link>
)}
</nav>
</div>
)
}
Pager.propTypes = {
pageContext: PropTypes.object.isRequired,
}
export default Pager
This code below is optional, but it displays the total number of pages based off your content. If you have 12 blog posts and display 6 posts per page, then it will say page 1 of 2.
{
numberOfPages > 1 && (
<div className="pager__location">
Page {humanPageNumber} of {numberOfPages}
</div>
)
}
The rest of the code just shows the previous and next button options.
Once you completed all those steps, restart your server and you will see the pagination displaying on your website.
If you run into any issues, feel free to send me a message!
Also, I'm documenting everything I'm learning and the projects I'm building on my Youtube channel. If you want to follow me along my coding journey, be sure to subscribe here