---
title: Pagination
---
The QPagination component is available for whenever a pagination system is required. It offers the user a simple UI for moving between items or pages.

There are two modes in which QPagination operates: with buttons only or with an inputbox. The latter allows the user to go to a specific page by clicking/tapping on the inputbox, typing the page number then hitting Enter key. If the new page number is within valid limits, the model will be changed accordingly.

## QPagination API

### Props

- `model-value` (number, required, syncable)
  Current page (must be between min/max)
- `min` (number | string, optional), default `1`
  Minimum page (must be lower than 'max')
- `max` (number | string, required)
  Number of last page (must be higher than 'min')
- `dark` (boolean, optional), default `null`
  Notify the component that the background is a dark color (useful when you are using it along with the 'input' prop)
- `size` (string, optional)
  Button size in CSS units, including unit name
  Examples: `'20px'`
- `disable` (boolean, optional)
  Put component in disabled mode
- `input` (boolean, optional)
  Use an input instead of buttons
- `icon-prev` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `icon-next` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `icon-first` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `icon-last` (string, optional)
  Icon name following Quasar convention; Make sure you have the icon library installed unless you are using 'img:' prefix; If 'none' (String) is used as value then no icon is rendered (but screen real estate will still be used for it)
  Examples: `'map'`, `'ion-add'`, `'img:https://cdn.quasar.dev/logo-v2/svg/logo.svg'`, `'img:path/to/some_image.png'`
- `to-fn` (Function, optional)
  Generate link for page buttons; For best performance, reference it from your scope and do not define it inline
  Function signature: `(page?: number) => object | string`
  Examples: `page => ({ query: { page } })`
  Params:
    - `page` (number, optional)
      Page number to navigate to
  Returns: `object | string`
    Object or String that can be passed to a <router-link> as 'to' parameter
- `boundary-links` (boolean, optional), default `null`
  Show boundary button links
- `boundary-numbers` (boolean, optional), default `null`
  Always show first and last page buttons (if not using 'input')
- `direction-links` (boolean, optional), default `null`
  Show direction buttons
- `ellipses` (boolean, optional), default `null`
  Show ellipses (...) when pages are available
- `max-pages` (number | string, optional), default `0`
  Maximum number of page links to display at a time; 0 means Infinite
- `flat` (boolean, optional)
  Use 'flat' design for non-active buttons (it's the default option)
- `outline` (boolean, optional)
  Use 'outline' design for non-active buttons
- `unelevated` (boolean, optional)
  Remove shadow for non-active buttons
- `push` (boolean, optional)
  Use 'push' design for non-active buttons
- `color` (string, optional), default `'primary'`
  Color name from the Quasar Color Palette for the non-active buttons
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `text-color` (string, optional)
  Text color name from the Quasar Color Palette for the ACTIVE buttons
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `active-design` (string, optional), default `''`
  The design of the ACTIVE button, similar to the flat/outline/push/unelevated props (but those are used for non-active buttons)
  Accepts: `'flat'`, `'outline'`, `'push'`, `'unelevated'`, `''`
- `active-color` (string, optional), default `'primary'`
  Color name from the Quasar Color Palette for the ACTIVE button
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `active-text-color` (string, optional)
  Text color name from the Quasar Color Palette for the ACTIVE button
  Examples: `'primary'`, `'teal'`, `'teal-10'`
- `round` (boolean, optional)
  Makes a circle shaped button for all buttons
- `rounded` (boolean, optional)
  Applies a more prominent border-radius for a squared shape button for all buttons
- `glossy` (boolean, optional)
  Applies a glossy effect for all buttons
- `gutter` (string, optional), default `'2px'`
  Apply custom gutter; Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl)
  Examples:
    - `'16px'`
    - `'10px 5px'`
    - `'2rem'`
    - `'xs'`
    - `'md lg'`
    - `'2px 2px 5px 7px'`
- `padding` (string, optional), default `'3px 2px'`
  Apply custom padding (vertical [horizontal]); Size in CSS units, including unit name or standard size name (none|xs|sm|md|lg|xl); Also removes the min width and height when set
  Examples:
    - `'16px'`
    - `'10px 5px'`
    - `'2rem'`
    - `'xs'`
    - `'md lg'`
    - `'2px 2px 5px 7px'`
- `input-style` (string | any[] | object, optional)
  Style definitions to be attributed to the input (if using one)
  Examples: `'background-color: #ff0000'`, `{ backgroundColor: '#ff0000' }`
- `input-class` (string | any[] | object, optional)
  Class definitions to be attributed to the input (if using one)
  Examples: `'my-special-class'`, `{ 'my-special-class': true }`
- `ripple` (boolean | object, optional), default `true`
  Configure buttons material ripple (disable it by setting it to 'false' or supply a config object); Does not applies to boundary and ellipsis buttons
  Examples:
    - `false`
    - `{ early: true, center: true, color: 'teal', keyCodes: [] }`

### Methods

- `set(pageNumber?: number): void`
  Go directly to the specified page
  Params:
    - `pageNumber` (number, optional)
      Page number to go to
- `setByOffset(offset?: number): void`
  Increment/Decrement current page by offset
  Params:
    - `offset` (number, optional)
      Offset page, can be negative or positive

### Events

- `@update:model-value`
  Emitted when the component needs to change the model; Is also used by v-model
  Params:
    - `value` (number, required)
      New model value

### Scoped Slots

- `#ellipsis`
  Replaces an ellipsis (...) button; Suggestion: QBtn (spread 'btnProps' onto it)
  Scope:
    - `side` (string, optional)
      Which ellipsis is being rendered
      Accepts: `'start'`, `'end'`
    - `page` (number, optional)
      The page the default ellipsis button navigates to (the first hidden page on that side)
    - `btnProps` (object, optional)
      Default QBtn props (design, color, size, label, disable, aria-label, ...) that can be binded to your own QBtn; deliberately does not contain the click handler or the 'to' prop
    - `onClick` (Function, optional)
      The default click handler (navigates to 'page'); bind it to your own QBtn to keep the default behavior
    - `to` (any, optional)
      The router link target the default ellipsis button would use; only present when the 'to-fn' prop is set
      Examples:
        - `'/page/4'`
        - `{ name: 'list', query: { page: 4 } }`

## Usage

### Design

Example "Standard":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination v-model="current" :max="5" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

The following are a few examples, but not an exhaustive list:

Example "Button design":

```vue
<template>
  <div class="q-gutter-md">
    <q-pagination
      v-model="current"
      max="5"
      direction-links
      flat
      color="grey"
      active-color="primary"
    />

    <q-pagination
      v-model="current"
      max="5"
      direction-links
      outline
      color="orange"
      active-design="unelevated"
      active-color="brown"
      active-text-color="orange"
    />

    <q-pagination
      v-model="current"
      max="5"
      direction-links
      push
      color="teal"
      active-design="push"
      active-color="orange"
    />

    <q-pagination
      v-model="current"
      :max="5"
      direction-links
      unelevated
      color="black"
      active-color="purple"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

Example "Gutter":

```vue
<template>
  <div class="q-gutter-md">
    <q-pagination v-model="current" max="5" direction-links />

    <q-pagination v-model="current" max="5" direction-links gutter="sm" />

    <q-pagination v-model="current" max="5" direction-links gutter="md" />

    <q-pagination v-model="current" max="5" direction-links gutter="20px" />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(2)
</script>
```

### Custom icons

Example "With icon replacement":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      :max="5"
      direction-links
      boundary-links
      icon-first="skip_previous"
      icon-last="skip_next"
      icon-prev="fast_rewind"
      icon-next="fast_forward"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

### With input

```vue
<template>
  <div class="flex flex-center">
    <q-pagination v-model="current" :max="5" input />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

Example "With input color":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      :max="5"
      input
      input-class="text-orange-10"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

### Max pages shown

Example "Maximum pages shown":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      color="black"
      :max="10"
      :max-pages="6"
      :boundary-numbers="false"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(5)
</script>
```

Example "Removing ellipses":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      color="teal"
      :max="10"
      :max-pages="5"
      :ellipses="false"
      :boundary-numbers="false"
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(5)
</script>
```

### Handling boundary

Example "With boundary numbers":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      color="purple"
      :max="10"
      :max-pages="6"
      boundary-numbers
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(6)
</script>
```

Example "With boundary links":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      color="deep-orange"
      :max="5"
      boundary-links
    />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

Example "With direction links":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination v-model="current" :max="5" direction-links />
  </div>
</template>

<script setup>
import { ref } from 'vue'

const current = ref(3)
</script>
```

### Custom ellipsis *(v2.30+)*

The `ellipsis` slot replaces the "..." buttons. Spread its `btnProps` onto your own QBtn to keep the default look, then attach whatever behavior you need: below, a [QPopupEdit](popup-edit.md) lets the user type the page number instead of jumping to the next hidden page. Bind the slot's `onClick` (or `to` when using `to-fn`) if you also want the default navigation.

Example "Go to page with QPopupEdit":

```vue
<template>
  <div class="flex flex-center">
    <q-pagination
      v-model="current"
      color="teal"
      :max="max"
      :max-pages="5"
      boundary-numbers
    >
      <template #ellipsis="{ btnProps }">
        <q-btn v-bind="btnProps" aria-label="Go to page">
          <q-popup-edit
            v-model="current"
            title="Go to page"
            :cover="false"
            :offset="[0, 8]"
            :validate="validatePage"
            #default="scope"
          >
            <q-input
              v-model.number="scope.value"
              type="number"
              :min="1"
              :max="max"
              dense
              autofocus
              @keyup.enter="scope.set"
            />
          </q-popup-edit>
        </q-btn>
      </template>
    </q-pagination>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const max = 20
const current = ref(10)

function validatePage(page) {
  return Number.isInteger(page) && page >= 1 && page <= max
}
</script>
```

### Localized digits *(v2.31+)*

The page numbers follow the `formatNumber` function of the active [language pack](../options/quasar-language-packs.md), when it defines one (see [QDate's localized digits](date.md#localized-digits)). The `fa` and `fa-IR` packs render Persian digits. The model and the `input` mode stay numeric.

## Accessibility *(v2.25+)*

QPagination renders as a `navigation` landmark. The first/previous/next/last buttons get localized `aria-label`s from the [Quasar Language Pack](../options/quasar-language-packs.md) in use, the numbered buttons are labeled with the page they lead to, and the active page's button is marked with `aria-current="page"`. The landmark itself is named from the same language pack (`pagination.label`); pass your own `aria-label` (it falls through to the root element) to tell several paginations on one page apart. It also carries `aria-disabled` at all times, reporting `true` or `false` according to the `disable` prop.

In input mode, the typed page number is committed when the user hits <kbd>Enter</kbd> or when the field loses focus.
