Pagination Control in SPFx with PnP React Controls

The SharePoint Framework ecosystem often needs pagination when displaying long datasets such as lists, search results, audit logs, or external APIs. Instead of building pagination logic from scratch, the PnP SPFx React Controls library provides a reusable Pagination control.

This control is lightweight, easy to integrate, and keeps your UI clean.


Why use Pagination?

Pagination improves performance and usability because:

  • Reduces rendering overhead.
  • Makes navigation easier for users.
  • Improves readability in large datasets.
  • Works well with APIs, PnPjs, and SharePoint lists.

Common scenarios:

  • Paginating SharePoint List items
  • Paginating Search Results
  • Paginating Audit Logs
  • Paginating Microsoft Graph data

Official Documentation

PnP official docs:

PnP Pagination Control Documentation

Related docs:

PnP SPFx React Controls

SPFx Documentation

Fluent UI React Documentation


Installation

Inside your current SPFx solution:

npm install @pnp/spfx-controls-react --save
npm install
heft start

Basic Example

Your example demonstrates a static pagination component:

import * as React from 'react';
import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";
const PaginationControlWp: React.FC = () => {
const _getPage = (page: number) => {
console.log('Page:', page);
};
return (
<Pagination
currentPage={3}
totalPages={13}
onChange={(page) => _getPage(page)}
limiter={3}
hideFirstPageJump
hideLastPageJump
limiterIcon={"Emoji12"}
/>
);
};
export default PaginationControlWp;

Code Breakdown

Import

import { Pagination } from "@pnp/spfx-controls-react/lib/pagination";

Imports the reusable Pagination control.


Current Page

currentPage={3}

Defines the currently selected page.

Example:

  • Page 1 = first page
  • Page 3 = active page
  • Page 13 = last page

Total Pages

totalPages={13}

Sets the maximum number of pages.

This is usually calculated like:

Math.ceil(totalItems / pageSize)

Example:

If you have 125 items and 10 per page:

Math.ceil(125 / 10) = 13

Page Change Event

onChange={(page) => _getPage(page)}

Triggered whenever the user clicks another page.

Your handler:

const _getPage = (page: number) => {
console.log('Page:', page);
};

Real-world usage:

const _getPage = async (page: number) => {
const items = await sp.web.lists
.getByTitle("Documents")
.items
.top(10)
.skip((page - 1) * 10)();
console.log(items);
};

Using PnPjs.


Limiter

limiter={3}

Controls how many page numbers appear around the current page.

Example:

Current page = 6

With limiter 3:

3 4 5 [6] 7 8 9

Without limiter:

1 2 3 4 5 6 7 8 9 10 11 12 13

Cleaner UI.


Hide First Jump

hideFirstPageJump

Removes:

<<

Useful for minimal navigation.


Hide Last Jump

hideLastPageJump

Removes:

>>

Keeps the component simpler.


Custom Limiter Icon

limiterIcon={"Emoji12"}

Uses a Fluent UI icon.

This changes the ellipsis visual.

Example:

Default:

...

Custom:

🙂

Fluent UI icons list:

Fluent UI Icons Reference


Real World Integration with SharePoint List

Example with list pagination:

const pageSize = 10;
const loadItems = async (page: number) => {
const items = await sp.web.lists
.getByTitle("Projects")
.items
.top(pageSize)
.skip((page - 1) * pageSize)();
setItems(items);
};

Pagination:

<Pagination
currentPage={currentPage}
totalPages={Math.ceil(totalItems / pageSize)}
onChange={loadItems}
/>

This is where the control becomes powerful.


Best Practices

Keep page size fixed

Example:

const pageSize = 10;

Avoid random sizes.


Cache results

Avoid re-fetching previous pages.


Combine with filters

Pagination + filters = better UX.

Example:

  • Category filter
  • Search box
  • Sorting

Show loading state

While changing pages:

{loading && <Spinner />}

Use Fluent UI Spinner.


When to Use

Use Pagination when:

✅ More than 20 records
✅ Search results
✅ Large SharePoint lists
✅ External APIs
✅ Graph data
✅ Audit logs

Avoid when:

❌ Small datasets
❌ Static content
❌ Simple dashboards


Final Thoughts

The PnP SPFx React Controls Pagination control saves time and integrates naturally into modern SharePoint Framework solutions.

Your current example is a perfect starting point and can easily evolve into:

  • SharePoint List paging
  • Graph paging
  • Search result paging
  • Custom API paging

This control becomes even stronger when combined with:

  • PnPjs
  • Fluent UI tables
  • ListView control
  • SearchBox
  • Filters

It is one of the most practical controls in the library for enterprise applications.

Edvaldo Guimrães Filho Avatar

Published by