Skip to content

Pagination

  • Search results or a long table split into pages
  • Moving to the next or previous page, or jumping to one

Not for a few steps of a form — show the steps instead — or a short list that fits on one page.

Choosing between moving around:

ComponentUse it forFor example
BreadcrumbShowing where the page sits in a hierarchy, with links up itHome / Projects / Website
PaginationMoving between pages of one long listSearch results, page 3 of 12
TabsSwitching between views within one pageOverview / Activity / Settings
LinkOne destination“Read the docs”

Showing page 6 of 20.

import { useState } from 'react';
import { Pagination } from '@arun-dev/ui';
// Buttons, with the page in state. With pages as URLs, pass getHref instead.
export default function PaginationBasics() {
const [page, setPage] = useState(6);
return (
<div style={{ display: 'grid', gap: 'var(--space-sm)' }}>
<Pagination page={page} count={20} onPageChange={setPage} />
<p style={{ margin: 0 }}>Showing page {page} of 20.</p>
</div>
);
}

Pagination shows the first and last pages, the current one with its neighbours, and an ellipsis for the rest. It always uses the same number of slots, so the row doesn’t change width as you move. The current page is marked aria-current="page".

The page is yours, so page and count are always given:

  • Pages are URLs (?page=3): pass getHref, and each page is a link. Opening one in a new tab works, and so does the back button.
  • Pages are state: pass onPageChange, and each page is a button.
<Pagination page={page} count={20} getHref={(p) => `?page=${p}`} />
<Pagination page={page} count={20} onPageChange={setPage} />

On the first or last page, Previous or Next is disabled. As a link it becomes plain text, since a link can’t be disabled.

paginationRange(page, count, siblings) returns the entries the component shows, numbers and 'ellipsis', so a layout of your own can use the same rules.

Pagination props
PropTypeDefaultDescription
pagenumberThe current page, from 1. Required.
countnumberHow many pages there are. Required.
siblingsnumber1Pages shown either side of the current one.
getHref(page: number) => stringEach page's address: pages become links. The right choice when pages are URLs.
onPageChange(page: number) => voidCalled with the page to go to. Without getHref, pages are buttons that call it.
labels{ previous?, next?, page? }Text of Previous and Next, and each page's accessible name — (p) => 'Page ' + p by default.