Pagination

A hand-drawn pager for splitting long lists across numbered pages.

Overview

Pagination splits a long list of results across numbered pages, with Previous/Next controls and an ellipsis that collapses large ranges. It is controlled — you own the current page and update it from onPageChange.

Anatomy

A <nav> landmark wrapping Previous, a run of numbered page buttons, and Next. Each button is a sketchy box (@ghds/sketch-core); the current page is filled and marked aria-current="page". Large gaps collapse to a single ellipsis, keeping the first, last, and the pages around the current one (siblingCount).

Variants & States

State Status Notes
Current page Implemented Filled + aria-current="page".
Disabled Implemented Previous on the first page and Next on the last.
Ellipsis Implemented Collapses a run of hidden pages; a single hidden page is shown instead.
Hover / Focus Implemented Standard button focus ring; keyboard operable.

Usage

Do

  • Keep it controlled: store the page and update it in onPageChange.
  • Tune siblingCount for how many neighbours to show around the current page.
  • Pair it with a results summary ("Showing 21–40 of 200") for context.

Don't

  • Don't use pagination for continuous feeds — infinite scroll or a Load more button fits better.
  • Don't hide Previous/Next; disable them at the ends instead.

Accessibility

Key Action
Tab Move between the pagination controls.
Enter / Space Activate the focused control.

Content

Numeric page labels, plus “Previous”/“Next” accessible labels. No visible prose beyond the numbers and chevron icons.

Props API

React@ghds/react

PropTypeDefaultDescription
countnumberTotal number of pages.
pagenumberCurrent page (1-based).
onPageChange(page: number) => voidFires with the next page.
siblingCountnumber1Pages shown on each side of the current one.
labelstring'Pagination'Accessible name for the nav landmark.

Web Components@ghds/web-components

PropTypeDefaultDescription
countnumberTotal number of pages.
pagenumberCurrent page (1-based).
siblingCountnumber1Pages shown on each side.
labelstring'Pagination'Accessible name.
page-change eventCustomEvent<number>Dispatched with the next page.

React Native@ghds/react-native

PropTypeDefaultDescription
countnumberTotal number of pages.
pagenumberCurrent page (1-based).
onPageChange(page: number) => voidFires with the next page.
siblingCountnumber1Pages shown on each side.
labelstring'Pagination'Accessible name.
testIDstringTest handle for queries.

Code examples

// React — @ghds/react
import { Pagination } from '@ghds/react/pagination';
import { useState } from 'react';

const [page, setPage] = useState(3);
<Pagination count={12} page={page} onPageChange={setPage} />;
<!-- Web Components — @ghds/web-components -->
<script type="module">
  import '@ghds/web-components/pagination';
</script>
<gh-pagination id="pager" count="12" page="3"></gh-pagination>
<script>
  const el = document.getElementById('pager');
  el.addEventListener('page-change', (e) => {
    el.page = e.detail;
  });
</script>
// React Native — @ghds/react-native
import { Pagination } from '@ghds/react-native/pagination';
import { useState } from 'react';

const [page, setPage] = useState(1);
<Pagination count={12} page={page} onPageChange={setPage} />;

Live Demo

React @ghds/react

Web Components @ghds/web-components