Skip to main content
The @zendeskgarden/react-pagination package provides two pagination variants: OffsetPagination for numbered page navigation, and CursorPagination for first/previous/next/last navigation. Both are fully accessible and keyboard-navigable.

Installation

npm install @zendeskgarden/react-pagination

# Peer dependencies
npm install react react-dom styled-components @zendeskgarden/react-theming
Place a ThemeProvider from @zendeskgarden/react-theming at the root of your React application. All Garden components must be rendered inside a ThemeProvider.

OffsetPagination

OffsetPagination renders a numbered page list with previous and next controls. It automatically shows gap indicators () when the total number of pages exceeds the visible window.

Basic usage

import React, { useState } from 'react';
import { ThemeProvider } from '@zendeskgarden/react-theming';
import { OffsetPagination } from '@zendeskgarden/react-pagination';

const Example = () => {
  const [currentPage, setCurrentPage] = useState(1);

  return (
    <ThemeProvider>
      <OffsetPagination
        totalPages={11}
        currentPage={currentPage}
        onChange={setCurrentPage}
      />
    </ThemeProvider>
  );
};

Customizing the page window

Use pagePadding to control how many pages appear on either side of the current page, and pageGap to control where gap indicators appear relative to the first and last pages.
const Example = () => {
  const [currentPage, setCurrentPage] = useState(5);

  return (
    <ThemeProvider>
      <OffsetPagination
        totalPages={20}
        currentPage={currentPage}
        onChange={setCurrentPage}
        pagePadding={3}
        pageGap={3}
      />
    </ThemeProvider>
  );
};

Localized labels

Provide the labels prop to override the accessible labels for previous, next, and gap elements, and to customize the per-page button label.
<OffsetPagination
  totalPages={10}
  currentPage={currentPage}
  onChange={setCurrentPage}
  labels={{
    previous: 'Previous page',
    next: 'Next page',
    gap: 'Pages omitted',
    renderPage: (page) => `Page ${page}`
  }}
/>

Props

currentPage
number
required
The currently active page number. Pages are 1-indexed.
totalPages
number
required
The total number of pages.
onChange
(currentPage: number) => void
Callback fired when the user navigates to a different page. Receives the new page number.
pagePadding
number
default:"2"
The number of pages to display on either side of the current page before showing a gap indicator.
pageGap
number
default:"2"
Controls the position of the leading and trailing gap indicators relative to the first and last pages.
labels
object
Localized accessible labels for pagination controls.

CursorPagination

CursorPagination provides first, previous, next, and last navigation controls without numbered pages. It is suitable for APIs that return cursor tokens rather than page numbers.

Basic usage

import { ThemeProvider } from '@zendeskgarden/react-theming';
import { CursorPagination } from '@zendeskgarden/react-pagination';

const Example = () => (
  <ThemeProvider>
    <CursorPagination aria-label="Ticket navigation">
      <CursorPagination.First onClick={() => goToFirst()}>First</CursorPagination.First>
      <CursorPagination.Previous onClick={() => goToPrevious()}>Previous</CursorPagination.Previous>
      <CursorPagination.Next onClick={() => goToNext()}>Next</CursorPagination.Next>
      <CursorPagination.Last onClick={() => goToLast()}>Last</CursorPagination.Last>
    </CursorPagination>
  </ThemeProvider>
);
Disable individual controls by passing the standard disabled prop. For example, disable CursorPagination.Previous and CursorPagination.First when on the first page.
const Example = ({ hasNextPage, hasPreviousPage }) => (
  <ThemeProvider>
    <CursorPagination aria-label="Results navigation">
      <CursorPagination.First disabled={!hasPreviousPage}>First</CursorPagination.First>
      <CursorPagination.Previous disabled={!hasPreviousPage}>Previous</CursorPagination.Previous>
      <CursorPagination.Next disabled={!hasNextPage}>Next</CursorPagination.Next>
      <CursorPagination.Last disabled={!hasNextPage}>Last</CursorPagination.Last>
    </CursorPagination>
  </ThemeProvider>
);

Subcomponents

CursorPagination exposes four navigation button subcomponents. Each accepts all ButtonHTMLAttributes<HTMLButtonElement> props.
SubcomponentDescription
CursorPagination.FirstNavigates to the first page
CursorPagination.PreviousNavigates to the previous page
CursorPagination.NextNavigates to the next page
CursorPagination.LastNavigates to the last page

Exports

The following are exported from @zendeskgarden/react-pagination:
ExportDescription
OffsetPaginationNumbered page pagination component
CursorPaginationFirst/previous/next/last cursor-based pagination

Build docs developers (and LLMs) love