Pagination
Pagination splits large amounts of data into pages, allowing users to navigate to any page. Configurable sibling and boundary ranges automatically calculate page ranges including ellipsis (…).
Playground
const [page, setPage] = useState(1)
<Pagination total={20} value={page} onChange={setPage} />Variants
Sizes
xssmdefaultlgxl| Size | Height | Font | Icon | Preview |
|---|---|---|---|---|
xs | 28px | 12px | 14px | |
sm | 32px | 13px | 14px | |
default | 36px | 14px | 16px | |
lg | 40px | 14px | 16px | |
xl | 48px | 16px | 16px |
Features
Edge Navigation (withEdges)
First/last jump buttons for quick navigation across many pages
<Pagination total={20} defaultValue={10} withEdges />Loop Navigation (loop)
Wraps from last page to first, and first page to last
<Pagination total={5} defaultValue={5} loop />Disabled State
Disables all interaction — useful during data loading
<Pagination total={10} defaultValue={3} disabled />Custom Icons
Replace built-in icons with any ReactNode via the icon prop
<Pagination total={10} defaultValue={5}>
<PaginationContent>
<PaginationItem>
<PaginationPrevious icon={
<svg className="icon-sm" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M10 19l-7-7m0 0l7-7m-7 7h18" />
</svg>
} />
</PaginationItem>
<PaginationItems />
<PaginationItem>
<PaginationNext icon={
<svg className="icon-sm" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
<path strokeLinecap="round" strokeLinejoin="round" d="M14 5l7 7m0 0l-7 7m7-7H3" />
</svg>
} />
</PaginationItem>
</PaginationContent>
</Pagination>API
Component Structure
Pagination— Pure React.ContentPage list container.ItemPage item wrapper.LinkPropsPage number button (page prop).PreviousPropsPrevious button.NextPropsNext button.FirstPropsFirst page button.LastPropsLast page button.EllipsisEllipsis.ItemsAuto-rendered paginationProps
Pagination
total1numberTotal number of pages
valueundefinednumberCurrent page (controlled mode)
defaultValue1numberInitial page (uncontrolled mode)
onChangeundefined(page: number) => voidCallback on page change
siblings1numberPages shown on each side of the current page
boundaries1numberPages always shown at the start and end
size"default""xs" | "sm" | "default" | "lg" | "xl"Component size (28/32/36/40/48px)
variant"default""default" | "outline" | "ghost"Visual variant
color"default""default" | "primary"Active page color
radius"md""sm" | "base" | "md" | "lg" | "xl" | "full"Border radius
disabledfalsebooleanDisables all interaction
withControlstruebooleanShow previous/next buttons
withEdgesfalsebooleanShow first/last jump buttons
loopfalsebooleanLoop from last to first page
| Name | Type | Default | Description |
|---|---|---|---|
total | number | 1 | Total number of pages |
value | number | undefined | Current page (controlled mode) |
defaultValue | number | 1 | Initial page (uncontrolled mode) |
onChange | (page: number) => void | undefined | Callback on page change |
siblings | number | 1 | Pages shown on each side of the current page |
boundaries | number | 1 | Pages always shown at the start and end |
size | "xs" | "sm" | "default" | "lg" | "xl" | "default" | Component size (28/32/36/40/48px) |
variant | "default" | "outline" | "ghost" | "default" | Visual variant |
color | "default" | "primary" | "default" | Active page color |
radius | "sm" | "base" | "md" | "lg" | "xl" | "full" | "md" | Border radius |
disabled | boolean | false | Disables all interaction |
withControls | boolean | true | Show previous/next buttons |
withEdges | boolean | false | Show first/last jump buttons |
loop | boolean | false | Loop from last to first page |
PaginationLink
pageundefinednumberTarget page number
isActiveautobooleanActive state (auto-detected from context if omitted)
| Name | Type | Default | Description |
|---|---|---|---|
page | number | undefined | Target page number |
isActive | boolean | auto | Active state (auto-detected from context if omitted) |
PaginationPrevious / PaginationNext / PaginationFirst / PaginationLast
iconBuilt-in SVG iconReactNodeCustom icon
| Name | Type | Default | Description |
|---|---|---|---|
icon | ReactNode | Built-in SVG icon | Custom icon |
Anatomy
36pxmin-w-9gap-1icon-smBest Practices
Do
- ✓Use pagination when the total data set is large
- ✓Clearly indicate the current page position
- ✓Configure siblings and boundaries for an appropriate page range
- ✓Use withEdges for large page counts to provide first/last jump buttons
Don't
- ✗Don't paginate small data sets — show all items instead
- ✗Don't skip resetting scroll position on page change
- ✗Don't display all page numbers at once — use siblings/boundaries
- ✗Avoid combining with infinite scroll
Accessibility
Keyboard
ARIA / WCAG
role="navigation"on the nav elementaria-label="pagination"— identifies the navigation regionaria-current="page"on the current pagearia-label="Go to page N"on each button- default 36px, lg 40px+ (WCAG 2.5.8 compliant)
aria-hidden="true"on Ellipsis