# Pagination
URL: https://ark-ui.com/docs/components/pagination
Source: https://raw.githubusercontent.com/chakra-ui/ark/refs/heads/main/website/src/content/pages/components/pagination.mdx
A navigation component that allows users to browse through pages.
---
## Anatomy
```tsx
```
## Examples
**Example: basic**
```ripple
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component Basic() {
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
}
```
### Controlled
To create a controlled Pagination component, manage the state of the current page using the `page` prop and update it
when the `onPageChange` event handler is called:
**Example: controlled**
```ripple
import { track } from 'ripple';
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component Controlled() {
let currentPage = track(1);
{
@currentPage = details.page;
}}
class={styles.Root}
>
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
}
```
### Root Provider
An alternative way to control the pagination is to use the `RootProvider` component and the `usePagination` hook. This
way you can access the state and methods from outside the component.
**Example: root-provider**
```ripple
import { Pagination, usePagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component RootProvider() {
const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 });
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
}
```
### Customization
You can customize the Pagination component by setting various props such as `dir`, `pageSize`, `siblingCount`, and
`translations`. Here's an example of a customized Pagination:
**Example: customized**
```ripple
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component Customized() {
`Page ${details.page}`,
}}
class={styles.Root}
>
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
}
```
### Context
Access pagination state and methods with `Pagination.Context` or the `usePaginationContext` hook. You get methods like
`setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like
`totalPages` and `pageRange`.
**Example: context**
```ripple
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight, ChevronsLeft, ChevronsRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component Context() {
component children({ context }) {
{'Page '}
{@context.page}
{' of '}
{@context.totalPages}
for (const user of @context.slice(users); key user.id) {
{user.name}{user.email}
}
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
}
```
### Page Range
Display the current page range information using the `pageRange` property. This shows which items are currently visible
(e.g., "Showing 1-10 of 100 results").
**Example: page-range**
```ripple
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component PageRange() {
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
{'Page '}
{@context.page}
{' of '}
{@context.totalPages}
}
}
```
### Page Size
Control the number of items per page dynamically using `setPageSize()`. This example shows how to integrate a native
select element to change the page size.
> **Note:** For uncontrolled behavior, use `defaultPageSize` to set the initial value. For controlled behavior, use
> `pageSize` and `onPageSizeChange` to programmatically manage the page size.
**Example: page-size-control**
```ripple
import { Pagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component PageSizeControl() {
component children({ context }) {
for (const [index, page] of @context.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
{'Page '}
{@context.page}
{' of '}
{@context.totalPages}
}
}
```
### Links
Create pagination with link navigation for better SEO and accessibility. This example shows how to use the pagination
component with anchor links instead of buttons.
**Example: link**
```ripple
import { Pagination, usePagination } from 'ark-ripple/pagination';
import { ChevronLeft, ChevronRight } from 'lucide-ripple';
import styles from 'styles/pagination.module.css';
export component Link() {
const pagination = usePagination(
{
type: 'link',
count: 100,
pageSize: 10,
siblingCount: 2,
getPageUrl: ({ page }) => `/page=${page}`,
},
);
for (const [index, page] of @pagination.pages.entries(); key page.value) {
if (page.type === 'page') {
{page.value}
} else {
{'…'}
}
}
}
```
## API Reference
### Props
**Component API Reference**
**Root Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
| `boundaryCount` | `number` | No | Number of pages to show at the beginning and end |
| `count` | `number` | No | Total number of data items |
| `defaultPage` | `number` | No | The initial active page when rendered.
Use when you don't need to control the active page of the pagination. |
| `defaultPageSize` | `number` | No | The initial number of data items per page when rendered.
Use when you don't need to control the page size of the pagination. |
| `getPageUrl` | `(details: PageUrlDetails) => string` | No | Function to generate href attributes for pagination links.
Only used when `type` is set to "link". |
| `ids` | `Partial<{
root: string
ellipsis: (index: number) => string
firstTrigger: string
prevTrigger: string
nextTrigger: string
lastTrigger: string
item: (page: number) => string
}>` | No | The ids of the elements in the accordion. Useful for composition. |
| `onPageChange` | `(details: PageChangeDetails) => void` | No | Called when the page number is changed |
| `onPageSizeChange` | `(details: PageSizeChangeDetails) => void` | No | Called when the page size is changed |
| `page` | `number` | No | The controlled active page |
| `pageSize` | `number` | No | The controlled number of data items per page |
| `siblingCount` | `number` | No | Number of pages to show beside active page |
| `translations` | `IntlTranslations` | No | Specifies the localized strings that identifies the accessibility elements and their states |
| `type` | `'button' | 'link'` | No | The type of the trigger element |
**Ellipsis Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `index` | `number` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**FirstTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**FirstTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | pagination |
| `[data-part]` | first-trigger |
| `[data-disabled]` | Present when disabled |
**Item Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `type` | `'page'` | Yes | |
| `value` | `number` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**Item Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | pagination |
| `[data-part]` | item |
| `[data-index]` | The index of the item |
| `[data-selected]` | Present when selected |
**LastTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**LastTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | pagination |
| `[data-part]` | last-trigger |
| `[data-disabled]` | Present when disabled |
**NextTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**NextTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | pagination |
| `[data-part]` | next-trigger |
| `[data-disabled]` | Present when disabled |
**PrevTrigger Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
**PrevTrigger Data Attributes:**
| Attribute | Value |
|-----------|-------|
| `[data-scope]` | pagination |
| `[data-part]` | prev-trigger |
| `[data-disabled]` | Present when disabled |
**RootProvider Props:**
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| `value` | `UsePaginationReturn` | Yes | |
| `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. |
### Context
**API:**
| Property | Type | Description |
|----------|------|-------------|
| `page` | `number` | The current page. |
| `count` | `number` | The total number of data items. |
| `pageSize` | `number` | The number of data items per page. |
| `totalPages` | `number` | The total number of pages. |
| `pages` | `Pages` | The page range. Represented as an array of page numbers (including ellipsis) |
| `previousPage` | `number` | The previous page. |
| `nextPage` | `number` | The next page. |
| `pageRange` | `PageRange` | The page range. Represented as an object with `start` and `end` properties. |
| `slice` | `(data: V[]) => V[]` | Function to slice an array of data based on the current page. |
| `setPageSize` | `(size: number) => void` | Function to set the page size. |
| `setPage` | `(page: number) => void` | Function to set the current page. |
| `goToNextPage` | `VoidFunction` | Function to go to the next page. |
| `goToPrevPage` | `VoidFunction` | Function to go to the previous page. |
| `goToFirstPage` | `VoidFunction` | Function to go to the first page. |
| `goToLastPage` | `VoidFunction` | Function to go to the last page. |