I created a simple GatsbyJS pagination component that would work in a similar way to my earlier ASP.NET Core version, where the user will be able to paginate through a list using the standard "Previous" and "Next" links as well as selecting individual page numbers.
Like the ASP.NET Core version, I have tried to make this pagination component very portable, so there shouldn't be any issues in adding this straight into your project. Plug and play!
import * as React from 'react'
import { Link } from 'gatsby'
import PropTypes from 'prop-types'
// Create URL path for numeric pagination
const getPageNumberPath = (currentIndex, basePath) => {
if (currentIndex === 1) {
return basePath
}
return `${basePath}/page-${(currentIndex)}`
}
// Create an object array of pagination numbers.
// The number of page numbers to render is set to 5.
const getPaginationGroup = (basePath, currentPage, pageCount, noOfPagesNos = 5) => {
let startPage = currentPage;
if (startPage === 1 || startPage === 2 || pageCount < noOfPagesNos)
startPage = 1;
else
startPage -= 2;
let maxPage = startPage + noOfPagesNos;
if (pageCount < maxPage) {
maxPage = pageCount + 1
}
if (maxPage - startPage !== noOfPagesNos && maxPage > noOfPagesNos) {
startPage = maxPage - noOfPagesNos;
}
let paginationInfo = [];
for (let i = startPage; i < maxPage; i++) {
paginationInfo.push({
number: i,
url: getPageNumberPath(i, basePath),
isCurrent: currentPage === i
});
}
return paginationInfo;
};
export const Pagination = ({ pageInfo, basePath }) => {
if (!pageInfo)
return null
const { currentPage, pageCount } = pageInfo
// Create URL path for previous and next buttons
const prevPagePath = currentPage === 2 ? basePath : `${basePath}/page-${(currentPage - 1)}`
const nextPagePath = `${basePath}/page-${(currentPage + 1)}`
if (pageCount > 1) {
return (
<ol>
{currentPage > 1 ?
<li>
<Link to={prevPagePath}>
Go to previous page
</Link>
</li> : null}
{getPaginationGroup(basePath, currentPage, pageCount).map((item, i) => {
return (
<li key={i}>
<Link to={item.url} className={`${item.isCurrent ? "is-current" : ""}`}>
Go to page {item.number}
</Link>
</li>
)
})}
{currentPage !== pageCount ?
<li>
<Link to={nextPagePath}>
Go to next page
</Link>
</li> : null}
</ol>
)
}
else {
return null
}
}
Pagination.propTypes = {
pageInfo: PropTypes.object,
basePath: PropTypes.string
}
export default Pagination;
This component requires just two parameters:
- pageInfo: A page context object created when Gatsby generates the site pages. The object should contain two properties consisting of the current page the that is being viewed (currentPage) and total number of pages (pageCount).
- basePath: The parent URL of where the pagination component will reside. For example, if your listing page is "/customers", this will be the base path. The pagination component will then prefix this to construct URL's in the format of - "/customers/page-2".