# Pagination

Navigation controls for moving between pages with numbered links, previous/next, and ellipsis.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown variants are available by appending `.md` to any URL or sending an `Accept: text/markdown` header. An agent skill is available at [/.well-known/agent-skills/site-skill.md](/.well-known/agent-skills/site-skill.md).





<ComponentThemeTabs>
  <ThemeTab name="mint">
    <PreviewWithCode name="pagination">
      <PaginationDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="berries">
    <PreviewWithCode name="pagination">
      <PaginationDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="citrine">
    <PreviewWithCode name="pagination">
      <PaginationDemo />
    </PreviewWithCode>
  </ThemeTab>

  <ThemeTab name="cinnamon">
    <PreviewWithCode name="pagination">
      <PaginationDemo />
    </PreviewWithCode>
  </ThemeTab>
</ComponentThemeTabs>

## With ellipsis [#with-ellipsis]

Use `PaginationEllipsis` between groups when the total page count is large. It renders a `…` icon and a screen-reader-only "More pages" label.

```tsx
<PaginationContent>
  <PaginationItem>
    <PaginationPrevious href="#" />
  </PaginationItem>
  <PaginationItem>
    <PaginationLink href="#">1</PaginationLink>
  </PaginationItem>
  <PaginationItem>
    <PaginationEllipsis />
  </PaginationItem>
  <PaginationItem>
    <PaginationLink href="#" isActive>5</PaginationLink>
  </PaginationItem>
  <PaginationItem>
    <PaginationEllipsis />
  </PaginationItem>
  <PaginationItem>
    <PaginationLink href="#">10</PaginationLink>
  </PaginationItem>
  <PaginationItem>
    <PaginationNext href="#" />
  </PaginationItem>
</PaginationContent>
```

## With router [#with-router]

Replace `href` with an `onClick` handler (or use Next.js `<Link>` via `asChild`) to integrate with client-side routing.

```tsx
"use client";

import { useRouter } from "next/navigation";

function PaginationWithRouter({ page, total }: { page: number; total: number }) {
  const router = useRouter();

  return (
    <Pagination>
      <PaginationContent>
        <PaginationItem>
          <PaginationPrevious
            href="#"
            onClick={(e) => {
              e.preventDefault();
              if (page > 1) router.push(`?page=${page - 1}`);
            }}
          />
        </PaginationItem>
        {Array.from({ length: total }, (_, i) => i + 1).map((p) => (
          <PaginationItem key={p}>
            <PaginationLink
              href={`?page=${p}`}
              isActive={p === page}
            >
              {p}
            </PaginationLink>
          </PaginationItem>
        ))}
        <PaginationItem>
          <PaginationNext
            href="#"
            onClick={(e) => {
              e.preventDefault();
              if (page < total) router.push(`?page=${page + 1}`);
            }}
          />
        </PaginationItem>
      </PaginationContent>
    </Pagination>
  );
}
```

## Props [#props]

### PaginationLink [#paginationlink]

| Prop       | Type                                  | Default  | Description                                                                  |
| ---------- | ------------------------------------- | -------- | ---------------------------------------------------------------------------- |
| `isActive` | `boolean`                             | `false`  | Marks the current page — applies `outline` variant and `aria-current="page"` |
| `size`     | `"default" \| "sm" \| "lg" \| "icon"` | `"icon"` | Button size; number links default to `icon` (square)                         |
| `href`     | `string`                              | —        | Navigation target                                                            |

### PaginationPrevious / PaginationNext [#paginationprevious--paginationnext]

<span className="block">
  Extends 

  `PaginationLink`

   with a fixed 

  `size="default"`

  , a chevron icon, and a responsive label ("Previous" / "Next") hidden on mobile.
</span>

## Usage [#usage]

```tsx
import {
  Pagination,
  PaginationContent,
  PaginationEllipsis,
  PaginationItem,
  PaginationLink,
  PaginationNext,
  PaginationPrevious,
} from "@/components/ui/pagination";

<Pagination>
  <PaginationContent>
    <PaginationItem>
      <PaginationPrevious href="/posts?page=1" />
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="/posts?page=1">1</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="/posts?page=2" isActive>2</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationLink href="/posts?page=3">3</PaginationLink>
    </PaginationItem>
    <PaginationItem>
      <PaginationNext href="/posts?page=3" />
    </PaginationItem>
  </PaginationContent>
</Pagination>
```

## Specs [#specs]

```md
# Mint — Pagination Specs

## Component
- name: pagination
- file: registry/mint/pagination.tsx
- installs to: components/ui/pagination.tsx
- dependencies: lucide-react
- registryDependencies: button

## What is it
A pure HTML pagination nav (no Radix dependency) for moving between numbered pages. It composes anchor elements styled via `buttonVariants` from the Button component, keeping page links visually consistent with the rest of the UI. Use it for any list or data set split across multiple pages; prefer a simpler Previous/Next pair when exact page numbers are not meaningful to the user.

## Visual identity
Page links inherit the Button component's ghost and outline variants — soft mint tones with subtle hover backgrounds and a clear outline on the active page. Compact icon-size squares (size-9) for numbered links give a dense, tidy row that scales well in tight layouts.

## Design tokens
--muted-foreground: oklch(0.52 0.06 155) / oklch(0.6 0.06 155)   — ellipsis icon colour
--border: oklch(0.88 0.04 155 / 60%) / oklch(0.32 0.05 155 / 40%)           — outline on active link (via buttonVariants outline)
--accent: oklch(0.92 0.05 155) / oklch(0.26 0.05 155)              — ghost hover background (via buttonVariants ghost)
--accent-foreground: oklch(0.32 0.1 155) / oklch(0.88 0.06 155)  — ghost hover text
--ring: oklch(0.5 0.14 155) / oklch(0.62 0.15 155)               — focus ring on links

## Sub-components
- Pagination          → `<nav role="navigation" aria-label="pagination">` — centred full-width wrapper
- PaginationContent   → `<ul>` — flex row, gap-1, items centred
- PaginationItem      → `<li>` — no visual output, structural wrapper
- PaginationLink      → `<a>` styled via buttonVariants; ghost by default, outline when isActive
- PaginationPrevious  → PaginationLink size="default" + ChevronLeftIcon + responsive "Previous" label
- PaginationNext      → PaginationLink size="default" + ChevronRightIcon + responsive "Next" label
- PaginationEllipsis  → `<span aria-hidden>` + MoreHorizontalIcon + sr-only "More pages"

## States
- isActive:    applies variant="outline" and aria-current="page" to the link
- data-active: set to true/undefined on PaginationLink for CSS targeting
- hover:       ghost links show accent background; outline link retains border
- focus:       3px ring in --ring colour on all links

## Conventions
- Sub-components expose data-slot="pagination", "pagination-content", "pagination-item", "pagination-link", "pagination-ellipsis" for CSS targeting
- PaginationLink defaults to size="icon" (size-9 square) — suitable for numbered pages
- PaginationPrevious and PaginationNext use size="default" and hide their text label below the sm breakpoint (hidden sm:block) — only icons on mobile
- Always wrap each PaginationLink, PaginationPrevious, PaginationNext, and PaginationEllipsis in a PaginationItem
- Use PaginationEllipsis between page groups when total pages exceed what can be shown; never use it at the start or end of the list
- For client-side routing, use asChild with a framework Link component or attach an onClick handler with e.preventDefault()
- PaginationPrevious carries aria-label="Go to previous page"; PaginationNext carries aria-label="Go to next page" — do not override without a suitable replacement
```

## Installation [#installation]

<CommandBox componentName="pagination" className="mt-2" />
