Pagination

A composed block for navigating paginated data. Combines first/previous/next/last navigation buttons with a page picker select and an optional items-per-page selector. Navigation buttons default to icon-only with visually hidden labels for accessibility.

Default

1 - 10 / 1000
/ 100
<script lang="ts">
  import Pagination from "../pagination.svelte";

  let page = $state(0);
</script>

<Pagination itemsTotal={1000} itemsPerPage={10} bind:page />

Visible Labels

Show text labels alongside icons on the navigation buttons by setting visuallyHidden: false on any label key. This is useful when space allows or when a more explicit UI is preferred.

1 - 10 / 100
/ 10
<script lang="ts">
  import Pagination from "../pagination.svelte";

  let page = $state(0);
</script>

<Pagination
  itemsTotal={100}
  itemsPerPage={10}
  bind:page
  labels={{
    first: { visuallyHidden: false },
    previous: { visuallyHidden: false },
    next: { visuallyHidden: false },
    last: { visuallyHidden: false },
  }}
/>

Props

Prop
page
page

Current page index. Uses 0-based indexing by default; set zeroBased={false} to switch to 1-based indexing. Supports bind: for two-way binding.

Type number
Default -
Required Yes
itemsTotal
itemsTotal

Total number of items across all pages.

Type number
Default -
Required Yes
itemsPerPage
itemsPerPage

Number of items displayed per page. The items-per-page selector offers options from [10, 20, 50, 100] filtered to those ≤ itemsTotal. Supports bind: for two-way binding.

Type number
Default -
Required Yes
zeroBased
zeroBased

When true, the page prop uses 0-based indexing (page 0 = first page). When false, uses 1-based indexing (page 1 = first page).

Type boolean
Default true
Required No
onChangePage
onChangePage

Callback fired whenever the current page changes, including navigation buttons and the page select. Receives the new page value and the previous page value.

Type (page: number, oldPage: number) => void
Default undefined
Required No
onChangeItemsPerPage
onChangeItemsPerPage

Callback fired when the items-per-page selection changes. The page resets to the first page automatically when this occurs.

Type (itemsPerPage: number) => void
Default undefined
Required No
onNext
onNext

Additional callback fired when the next page button is clicked, after the page has been updated.

Type () => void
Default undefined
Required No
onPrevious
onPrevious

Additional callback fired when the previous page button is clicked, after the page has been updated.

Type () => void
Default undefined
Required No
onFirst
onFirst

Additional callback fired when the first page button is clicked, after the page has been updated.

Type () => void
Default undefined
Required No
onLast
onLast

Additional callback fired when the last page button is clicked, after the page has been updated.

Type () => void
Default undefined
Required No
labels
labels

Override the text or visibility for each navigation label. Each key accepts text (string) to change the label copy and visuallyHidden (boolean) to toggle screen-reader-only vs visible. Keys: "page", "first", "previous", "next", "last", "itemsPerPage". Navigation buttons default to visuallyHidden: true (icon-only with aria-label).

Type { [key in "page" | "first" | "previous" | "next" | "last" | "itemsPerPage"]?: { text?: string; visuallyHidden?: boolean } }
Default undefined
Required No
...rest
...rest

Standard HTML div attributes passed to the pagination root element.

Type HTMLAttributes<HTMLDivElement>
Default -
Required No