Pagination

A navigation component for paginated content with ellipsis support.

$ npx @beaket/ui add pagination
Source
import { useState } from "react";

import { Pagination } from "@/components/ui/pagination";

export default function Example() {
  const [page, setPage] = useState(1);

  return (
    <div className="flex h-full items-center justify-center">
      <Pagination
        mode="button"
        page={page}
        totalPages={20}
        maxPageButtons={7}
        onPageChange={setPage}
      />
    </div>
  );
}

Examples

All States

First Page (Link Mode)

Middle Page (Link Mode)

Last Page (Link Mode)

Few Pages (3)

Many Pages with Ellipsis

Single Page (Hidden)

Pagination is hidden when totalPages = 1

Button Mode — First Page

Button Mode — Middle Page

Button Mode — Last Page

Source
import { useState } from "react";

import { Pagination } from "@/components/ui/pagination";

const buildPageUrl = (page: number) => `?page=${page}`;

export default function PaginationStatesExample() {
  const [firstPage, setFirstPage] = useState(1);
  const [middlePage, setMiddlePage] = useState(5);
  const [lastPage, setLastPage] = useState(10);

  return (
    <div className="space-y-8">
      <div>
        <h3 className="mb-4 text-sm font-medium">First Page (Link Mode)</h3>
        <Pagination page={1} totalPages={10} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Middle Page (Link Mode)</h3>
        <Pagination page={5} totalPages={10} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Last Page (Link Mode)</h3>
        <Pagination page={10} totalPages={10} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Few Pages (3)</h3>
        <Pagination page={2} totalPages={3} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Many Pages with Ellipsis</h3>
        <Pagination page={50} totalPages={100} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Single Page (Hidden)</h3>
        <p className="text-fg-muted text-sm">Pagination is hidden when totalPages = 1</p>
        <Pagination page={1} totalPages={1} buildPageUrl={buildPageUrl} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Button Mode — First Page</h3>
        <Pagination mode="button" page={firstPage} totalPages={10} onPageChange={setFirstPage} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Button Mode — Middle Page</h3>
        <Pagination mode="button" page={middlePage} totalPages={10} onPageChange={setMiddlePage} />
      </div>

      <div>
        <h3 className="mb-4 text-sm font-medium">Button Mode — Last Page</h3>
        <Pagination mode="button" page={lastPage} totalPages={10} onPageChange={setLastPage} />
      </div>
    </div>
  );
}

Props

NameTypeDefaultDescription
modeundefined | button | link—Use link-based navigation (default). Renders `<a>` tags for SSR-friendly navigation. Use button-based navigation for client-side pagination. Renders `<button>` tags with onClick handlers.
buildPageUrl((page: number) => string) | ((page: number) => string) | undefined—Function to build URL for a given page number. Required when mode is "link". Used by `Pagination.Item` when it renders its own `<a href>`.
onPageChange((page: number) => void) | ((page: number) => void) | undefined—Callback when a page is selected. Required when mode is "button". Used by `Pagination.Item` when it renders its own `<button>`.
childrenReactNode—Compose the strip yourself from `Pagination.Previous`, `.Item`, `.Ellipsis` and `.Next` instead of letting the root lay it out.
labelsPaginationLabels | undefined—Accessible names; omitted labels retain their English defaults.
page*number—Current page number (1-indexed)
totalPages*number—Total number of pages
maxPageButtonsnumber | undefined—Maximum number of page buttons to show (default: 5) When there are more pages, ellipsis will be shown
Item.page*number—The page this cell navigates to
Item.asChildbooleanfalseRenders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>`
Previous.asChildboolean—Renders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>`
Next.asChildboolean—Renders the consumer's own element (a router `Link`) instead of an `<a>`/`<button>`
Ellipsis.asChildbooleanfalseRenders the consumer's own element instead of a `<span>`