Skip to main content

Pagination

Pagination renders previous and next buttons, page-number buttons, and ellipses for large page ranges. Optional edge buttons move to the first or last page.

Open in Storybook

Import​

import { Pagination } from "@tosui/react";

Basic usage​

Controlled state​

Pass page when application state or data loading owns the current page. Update that state from onPageChange.

function PaginatedContent() {
const [page, setPage] = useState(1);

return (
<Pagination page={page} totalPages={10} onPageChange={setPage} />
);
}

Page ranges​

Pagination automatically shows ellipsis for large page ranges.

// Few pages - all shown
<Pagination page={1} totalPages={5} showEdges={false} onPageChange={setPage} />
// Shows: « 1 2 3 4 5 »

// Many pages - ellipsis shown
<Pagination page={5} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 4 5 6 … 20 »

// Near start
<Pagination page={2} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 2 3 4 5 … 20 »

// Near end
<Pagination page={19} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 16 17 18 19 20 »

Siblings​

Control how many page numbers appear on each side of the current page.

// 1 sibling (default)
<Pagination page={10} totalPages={20} siblings={1} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 9 10 11 … 20 »

// 2 siblings
<Pagination page={10} totalPages={20} siblings={2} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 8 9 10 11 12 … 20 »

First-page and last-page buttons​

Set showEdges={false} to hide the buttons that move directly to the first or last page. The numbered range still includes the first and last page.

// With edge buttons (default)
<Pagination page={5} totalPages={20} showEdges onPageChange={setPage} />
// Shows: «« « 1 … 4 5 6 … 20 » »»

// Without edge buttons
<Pagination page={5} totalPages={20} showEdges={false} onPageChange={setPage} />
// Shows: « 1 … 4 5 6 … 20 »

Complete example​

function ProductList() {
const [page, setPage] = useState(1);
const { products, totalPages } = useProducts({ page, limit: 10 });

return (
<VStack gap={6}>
<Box>
{products.map(product => (
<ProductCard key={product.id} product={product} />
))}
</Box>

<Pagination
page={page}
totalPages={totalPages}
onPageChange={setPage}
/>
</VStack>
);
}

Props reference​

PropTypeDefaultDescription
pagenumber-Current page for controlled usage (1-indexed)
defaultPagenumber1Initial page for uncontrolled usage
totalPagesnumber-Total number of pages (required)
onPageChange(page: number) => void-Optional page change callback
siblingsnumber1Number of page numbers on each side of current
showEdgesbooleantrueShow first/last page buttons
classNamestring-Additional CSS class

Button states​

  • The previous and first-page buttons are disabled on page 1.
  • The next and last-page buttons are disabled on the final page.
  • The current page button uses the solid variant.
  • Other page buttons use the ghost variant.

Accessibility​

  • A nav element wraps the controls and uses aria-label="Pagination".
  • Each button has a page or action label, such as Page 5 or Previous page.
  • The current page uses aria-current="page".
  • Unavailable actions use the native disabled attribute.

TypeScript​

import { Pagination, type PaginationProps } from "@tosui/react";