Free and open-source React pagination components built for modern applications and websites. These pagination components are built using React Aria and styled with Tailwind CSS.
Installation
You can add this pagination component using our CLI or manually:
npx untitledui@latest add pagination
Pagination examples
Below are examples and variations of this pagination component:
API reference
Import the parts and assemble them:
import { Pagination } from "@/components/application/pagination/pagination-base"; <Pagination.Root page={page} total={total}> <Pagination.PrevTrigger /> <Pagination.Context> {({ pages }) => ( <> <Pagination.Item /> <Pagination.Ellipsis /> </> )} </Pagination.Context> <Pagination.NextTrigger /> </Pagination.Root>
Pagination.Context
Pagination.Ellipsis
Renders a <span> element.
Pagination.Item
Renders a <button> element.
Pagination.Item
Import Pagination from @/components/application/pagination/pagination and use it as Pagination.Item.
Pagination.NextTrigger
Pagination.PrevTrigger
Pagination.Root
Renders a <nav> element.
PaginationCardAdvanced
Import PaginationCardAdvanced from @/components/application/pagination/pagination. Renders a <div> element.
PaginationCardDefault
Import PaginationCardDefault from @/components/application/pagination/pagination. Renders a <div> element.
PaginationCardMinimal
Import PaginationCardMinimal from @/components/application/pagination/pagination. Renders a <div> element.
PaginationDot
Import PaginationDot from @/components/application/pagination/pagination-dot.
PaginationLine
Import PaginationLine from @/components/application/pagination/pagination-line.
PaginationPageDefault
Import PaginationPageDefault from @/components/application/pagination/pagination. Renders a <div> element.
PaginationPageMinimalCenter
Import PaginationPageMinimalCenter from @/components/application/pagination/pagination. Renders a <div> element.
FAQs
Please refer to our frequently asked questions page for more.
pagination.tsx exports PaginationPageDefault, PaginationPageMinimalCenter, PaginationCardDefault, PaginationCardMinimal, PaginationButtonGroup and PaginationCardAdvanced. Two carousel-style indicators live in their own files: PaginationDot and PaginationLine, both of which take a size of "md" or "lg" (default "md") and a framed flag for the translucent pill background.
It is fully controlled. You pass the current page as page (1-based) and the number of pages as total, and the component calls onPageChange(page: number) with the new page number. It never stores the page internally, so nothing moves until you update your own state. On Pagination.Root, PaginationDot and PaginationLine both props are required and have no default; the flat variants such as PaginationPageDefault, PaginationCardMinimal and PaginationCardAdvanced fall back to page = 1 and total = 10 when you omit them.
Because page and onPageChange are the whole API, read the current page from wherever it lives — a URL search param, for example — and push a new URL inside onPageChange instead of calling setState. Compute total as the page count, not the row count: Math.ceil(totalItems / pageSize).
Use siblingCount, which defaults to 1 and sets how many pages appear on each side of the current page. The component renders every page without ellipsis while siblingCount * 2 + 5 is greater than or equal to total, and otherwise collapses the run with Pagination.Ellipsis while always keeping the first and last page visible. PaginationCardMinimal and PaginationCardAdvanced don't accept siblingCount.
Yes — PaginationCardMinimal and PaginationCardAdvanced accept pageSize (default 10) and onPageSizeChange, and render a Select with 10, 25, 50 and 100 options. PaginationCardAdvanced additionally renders an editable page number input and first/last page jump buttons.
PaginationCardMinimal and PaginationButtonGroup accept align with "left", "center" or "right" (default "left"), while PaginationCardAdvanced accepts "space-between" or "center" (default "space-between"). The rounded prop, which switches the number buttons from rounded-lg to rounded-full, is accepted by three variants only: PaginationPageDefault, PaginationPageMinimalCenter and PaginationCardDefault. PaginationCardMinimal, PaginationCardAdvanced and PaginationButtonGroup do not take it.
Pagination.Root renders a <nav aria-label="Pagination Navigation">. Each page button gets aria-current="page" when it is the current page and an aria-label of "Page {value}", the ellipsis is aria-hidden, and the previous and next triggers are labelled "Previous Page" and "Next Page" and are automatically disabled on the first and last page. Those button labels are the ones you can override: Pagination.Item, Pagination.PrevTrigger and Pagination.NextTrigger each take an ariaLabel prop. The <nav> label is hardcoded on Pagination.Root, so change it by editing the component. PaginationCardMinimal is the exception: it doesn't use Pagination.Root and renders its own <nav aria-label="Pagination"> with plain Previous and Next buttons.