# 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 To set up the pagination correctly, you'll need to understand its anatomy and how we name its parts. > Each part includes a `data-part` attribute to help identify them in the DOM. ## Examples Learn how to use the `Pagination` component in your project. Let's take a look at the most basic example: **Example: basic** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' export const Basic = () => ( Previous Page {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) } Next Page ) ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const Basic = () => ( Previous Page {(api) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )} Next Page ) ``` #### Vue ```vue ``` #### Svelte ```svelte Previous Page {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet} Next Page ``` ### Controlled Pagination 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** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' import { useState } from 'react' export const Controlled = () => { const [currentPage, setCurrentPage] = useState(1) return ( setCurrentPage(details.page)} > Previous {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) } Next Page ) } ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For, createSignal } from 'solid-js' export const Controlled = () => { const [currentPage, setCurrentPage] = createSignal(1) return ( setCurrentPage(details.page)} > Previous Page {(api) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )} Next Page ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Previous {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet} Next Page ``` ### Customizing Pagination 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** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' export const Customized = () => ( `Page ${details.page}`, }} > Previous {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) } Next Page ) ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const Customized = () => { return ( `Page ${details.page}`, }} > Previous Page {(api) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )} Next Page ) } ``` #### Vue ```vue ``` #### Svelte ```svelte `Page ${details.page}`, }} > Previous {#snippet render(pagination)} {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} {/snippet} Next Page ``` ### Using Context The `Context` component provides access to the pagination state and methods through a render prop pattern. This allows you to access methods like `setPage`, `setPageSize`, `goToNextPage`, `goToPrevPage`, `goToFirstPage`, `goToLastPage`, as well as properties like `totalPages` and `pageRange`. **Example: context** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' export const Context = () => { return ( {(pagination) => (

Page {pagination.page} of {pagination.totalPages}

Items {pagination.pageRange.start + 1}-{pagination.pageRange.end}

)}
) } ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' export const Context = () => { return ( {(api) => (

Page {api().page} of {api().totalPages}

Items {api().pageRange.start + 1}-{api().pageRange.end}

)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

Page {pagination().page} of {pagination().totalPages}

Items {pagination().pageRange.start + 1}-{pagination().pageRange.end}

{/snippet}
``` ### Data Slicing Use the `slice()` method to paginate actual data arrays. This method automatically slices your data based on the current page and page size. **Example: data-slicing** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' const items = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`) export const DataSlicing = () => { return ( {(pagination) => (

Current Page Items:

    {pagination.slice(items).map((item) => (
  • {item}
  • ))}
Previous {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )} Next
)}
) } ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' const items = Array.from({ length: 100 }, (_, i) => `Item ${i + 1}`) export const DataSlicing = () => { return ( {(api) => (

Current Page Items:

    {(item) =>
  • {item}
  • }
Previous {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } Next
)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}

Current Page Items:

    {#each pagination().slice(items) as item}
  • {item}
  • {/each}
Previous {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} Next
{/snippet}
``` ### Page Range Display 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** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' export const PageRange = () => { return ( {(pagination) => (
Previous {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )} Next

Showing {pagination.pageRange.start + 1}-{pagination.pageRange.end} of {pagination.count} results

Page {pagination.page} of {pagination.totalPages}

)}
) } ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const PageRange = () => { return ( {(api) => (
Previous {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } Next

Showing {api().pageRange.start + 1}-{api().pageRange.end} of {api().count} results

Page {api().page} of {api().totalPages}

)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
Previous {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} Next

Showing {pagination().pageRange.start + 1}-{pagination().pageRange.end} of {pagination().count} results

Page {pagination().page} of {pagination().totalPages}

{/snippet}
``` ### Page Size Control 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. **Example: page-size-control** #### React ```tsx import { Pagination } from '@ark-ui/react/pagination' export const PageSizeControl = () => { return ( {(pagination) => (
Previous {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )} Next

Page {pagination.page} of {pagination.totalPages}

)}
) } ``` #### Solid ```tsx import { Pagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const PageSizeControl = () => { return ( {(api) => (
Previous {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } Next

Page {api().page} of {api().totalPages}

)}
) } ``` #### Vue ```vue ``` #### Svelte ```svelte {#snippet render(pagination)}
Previous {#each pagination().pages as page, index} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} Next

Page {pagination().page} of {pagination().totalPages}

{/snippet}
``` ### Link Pagination 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** #### React ```tsx import { Pagination, usePagination } from '@ark-ui/react/pagination' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return ( Previous {pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), )} Next ) } ``` #### Solid ```tsx import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const Link = () => { const pagination = usePagination({ type: 'link', count: 100, pageSize: 10, siblingCount: 2, getPageUrl: ({ page }) => `/page=${page}`, }) return ( Previous {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } Next ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Previous {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} Next ``` ### Root Provider The `RootProvider` component provides a context for the pagination. It accepts the value of the `usePagination` hook. You can leverage it to access the component state and methods from outside the pagination. **Example: root-provider** #### React ```tsx import { Pagination, usePagination } from '@ark-ui/react/pagination' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return ( <> Previous Page {(pagination) => pagination.pages.map((page, index) => page.type === 'page' ? ( {page.value} ) : ( ), ) } Next Page ) } ``` #### Solid ```tsx import { Pagination, usePagination } from '@ark-ui/solid/pagination' import { For } from 'solid-js' export const RootProvider = () => { const pagination = usePagination({ count: 5000, pageSize: 10, siblingCount: 2 }) return ( <> Previous Page {(api) => ( {(page, index) => page.type === 'page' ? ( {page.value} ) : ( ) } )} Next Page ) } ``` #### Vue ```vue ``` #### Svelte ```svelte Previous Page {#each pagination().pages as page, index (index)} {#if page.type === 'page'} {page.value} {:else} {/if} {/each} Next Page ``` > If you're using the `RootProvider` component, you don't need to use the `Root` component. ## API Reference ### Props **Component API Reference** #### React **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `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. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: 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. | **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 | **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. | #### Solid **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `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. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: 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` | `'link' | 'button'` | No | The type of the trigger element | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `(props: ParentProps<'div'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `(props: ParentProps<'button'>) => Element` | 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 | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `(props: ParentProps<'button'>) => Element` | 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` | `(props: ParentProps<'button'>) => Element` | 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` | `(props: ParentProps<'nav'>) => Element` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Vue **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `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. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis(index: number): string prevTrigger: string nextTrigger: string item(page: number): string }>` | No | The ids of the elements in the accordion. Useful for composition. | | `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. | **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 | **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` | `PaginationApi` | Yes | | | `asChild` | `boolean` | No | Use the provided child element as the default rendered element, combining their props and behavior. | #### Svelte **Root Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `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. | | `id` | `string` | No | The unique identifier of the machine. | | `ids` | `Partial<{ root: string ellipsis: (index: number) => string prevTrigger: string nextTrigger: 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 | | `ref` | `Element` | No | | | `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` | `'link' | 'button'` | No | The type of the trigger element | **Context Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `render` | `Snippet<[UsePaginationContext]>` | Yes | | **Ellipsis Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `index` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'div'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `type` | `'page'` | Yes | | | `value` | `number` | Yes | | | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **Item Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | item | | `[data-index]` | The index of the item | | `[data-selected]` | Present when selected | **NextTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **NextTrigger Data Attributes:** | Attribute | Value | |-----------|-------| | `[data-scope]` | pagination | | `[data-part]` | next-trigger | | `[data-disabled]` | Present when disabled | **PrevTrigger Props:** | Prop | Type | Required | Description | |------|------|----------|-------------| | `asChild` | `Snippet<[PropsFn<'button'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | **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` | `Snippet<[PropsFn<'nav'>]>` | No | Use the provided child element as the default rendered element, combining their props and behavior. | | `ref` | `Element` | No | | ### Context These are the properties available when using `Pagination.Context`, `usePaginationContext` hook or `usePagination` hook. **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. |