Pagination Nav

Quick first, previous, next, last, and page buttons for navigation based pagination, supporting regular links or router links.

Overview

<b-pagination-nav> is a custom input component that provides navigational pagination. The total number of pages set with the number-of-pages prop. Page numbers are indexed from 1 through number-of-pages.

b-pagination-nav will try and auto-detect which page link is active page button based on the current page's URL (via either $route detection or, if no $router detected, the browser location URL).

Note: <b-pagination-nav> is used for navigating to new page URLs. For controlling in page component pagination (such as table or list pagination), use the <b-pagination> component instead.

<template>
  <div class="overflow-auto">
    <b-pagination-nav :link-gen="linkGen" :number-of-pages="10" use-router></b-pagination-nav>
  </div>
</template>

<script>
  export default {
    methods: {
      linkGen(pageNum) {
        return pageNum === 1 ? '?' : `?page=${pageNum}`
      }
    }
  }
</script>

<!-- b-pagination-nav-lead.vue -->

By default, <b-pagination-nav> generates plain link tags, setting the HREF attribute to base-url concatenated with the page number. The base-url prop defaults to '/'. The number of pages is specified via the number-of-pages prop. Pages are numbers from 1 through to number-of-pages.

To generate page links as <router link> components (or <nuxt-link> if Nuxt.js is detected), set the use-router prop. The HREF will then become the to prop of the router link. Or, optionally, use a link generator function to return a router-link to location object.

If a $router is not detected on your app, <b-pagination-nav> will fallback to regular <a> elements, and any to location object will be converted to a standard URL (if possible).

The following router link specific props are supported:

  • active-class
  • exact
  • exact-active-class
  • prefetch (<nuxt-link> specific prop)
  • no-prefetch (<nuxt-link> specific prop)

For details on the above props, refer to the Router Link Support reference section.

If you need finer grained control over the generated link URLs or <router-link> to props, you may set the link-gen prop to a function reference that receives two arguments: the page number, and an object containing two fields (link and page), where page is the page number and link is the internally generated link.

The link-gen function should return either a string (for HREF) or a router to object. If the returned value is an object, then a router-link will always be generated (if a $router is detected). If the return value is a string, a standard link is generated by default unless the use-router prop is set. If a to location object is used, then the base-url prop will have no effect.

export default {
  methods: {
    // For regular HREF (or string `to` prop if `use-router` is set)
    linkGen(pageNum) {
      return `/foo/page/${pageNum}`
    },

    // Returning a router-link `to` object
    linkGen(pageNum) {
      return { path: `/foo/page/${pageNum}` }
    },

    // Returning a router-link `to` object with query parameters
    linkGen(pageNum) {
      return {
        path: '/foo/',
        query: { page: pageNum }
      }
    },

    // Returning a router-link `to` object with named route and parameters
    linkGen(pageNum) {
      return {
        name: 'posts',
        params: { post: pageNum }
      }
    }
  }
}

Note: when falling back from a to location object to a standard link (when no $router is available), only the following location properties are used to generate the URL:

  • path (if not provided defaults to the page's current URL path)
  • query
  • hash (must include the leading # if used)

The conversion of name routes and params is not supported.

Page number generation

By default, <b-pagination-nav> renders page numbers (1-N) in the page link buttons. You can override this behaviour by supplying a function reference to the page-gen property. The function reference should accept a single argument which is a page number (1-N). The page-gen function should return a string.

Note: HTML content in generated page number strings is not supported. For basic HTML, you can use the scoped slot page for finer-grained formatting.

Example: Using an array of links to generate pagination:

<template>
  <div class="overflow-auto">
    <b-pagination-nav
      :link-gen="linkGen"
      :page-gen="pageGen"
      :number-of-pages="links.length"
    ></b-pagination-nav>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        links: ['#foo', '#bar', '#baz', '#faz']
      }
    },
    methods: {
      linkGen(pageNum) {
        return this.links[pageNum - 1]
      },
      pageGen(pageNum) {
        return this.links[pageNum - 1].slice(1)
      }
    }
  }
</script>

<!-- b-pagination-nav-links.vue -->

Providing an array of pages

Rather than using number-of-pages to auto generate page links, you can pass an array of links via the pages prop. When the pages prop has an array of length 1 or greater, it will be used to generate the page links.

The array can be one of two formats:

  • Array of strings, where each entry is a link. in this mode, the page button numbers will automatically be set to 1 through to the number of entries in the array.
  • Array of objects, where each object has two fields: link (required) and text (optional). Link can be be either a string specifying the link, or a to location object. text will be the content of the page link buttons. If text is omitted, page button content will default to the page number.

When a string link is provided, <b-pagination-nav> will use regular <a> elements, unless the use-router prop is set. When link (in the array of objects form) is a to location object, then a router link will automatically be generated (if a $router is detected).

With the array format, link strings (and/or location objects) are used as-as and base-url prop will be ignored.

<template>
  <b-pagination-nav :pages="pages1" use-router></b-pagination-nav>
  <b-pagination-nav :pages="pages2" use-router></b-pagination-nav>
  <b-pagination-nav :pages="pages3" use-router></b-pagination-nav>
</template>

<script>
export default {
  data() {
    return {
      // Simple array of strings
      pages1: ['?page=1', '?page=2', '?page=3'],
      // Array of objects with string links
      pages2: [
        { link: '?page=1', text: 'One' },
        { link: '?page=2', text: 'Two' },
        { link: '?page=3', text: 'Three' }
      ],
      // Array of objects with router `to` locations
      pages3: [
        { link: { query: { page: 1 } }, text: 'Page 1' },
        { link: { query: { page: 2 } }, text: 'Page 2' },
        { link: { query: { page: 3 } }, text: 'Page 3' }
      ]
    }
  }
}
</script>

<!-- pagination-nav-array.vue -->

Customizing appearance

Limiting the number of displayed buttons

To restrict the number of page buttons (including the ellipsis, but excluding the first, prev, next, and last buttons) shown, use the limit prop to specify the desired number of page buttons (including the ellipsis, if shown). The default limit is 5. The minimum supported value is 3. When limit is set to 3, no ellipsis indicators will be shown for practical purposes.

The first and last buttons can be optionally hidden by setting the hide-goto-end-buttons prop.

The showing of the ellipsis can be optionally disabled by setting the hide-ellipsis prop.

Small screen support

On smaller screens (i.e. mobile), some of the <b-pagination-nav> buttons will be hidden to minimize the potential of the pagination interface wrapping onto multiple lines:

  • The ellipsis indicators will be hidden on screens xs and smaller.
  • Page number buttons will be limited to a maximum of 3 visible on xs screens and smaller.

This ensures that no more than 3 page number buttons are visible, along with the goto first, prev, next, and last buttons.

Button content

<b-pagination-nav> supports several props/slots that allow you to customize the appearance. All *-text props are text-only and strip out HTML but you can use their equally named slot counterparts for that.

For a full list of all available slots see the Slots section below.

<template>
  <div class="overflow-auto">
    <!-- Use text in props -->
    <b-pagination-nav
      number-of-pages="10"
      base-url="#"
      first-text="First"
      prev-text="Prev"
      next-text="Next"
      last-text="Last"
    ></b-pagination-nav>

    <!-- Use emojis in props -->
    <b-pagination-nav
      number-of-pages="10"
      base-url="#"
      first-text="⏮"
      prev-text="⏪"
      next-text="⏩"
      last-text="⏭"
      class="mt-4"
    ></b-pagination-nav>

    <!-- Use HTML and sub-components in slots -->
    <b-pagination-nav
      number-of-pages="10"
      base-url="#"
      class="mt-4"
    >
      <template #first-text><span class="text-success">First</span></template>
      <template #prev-text><span class="text-danger">Prev</span></template>
      <template #next-text><span class="text-warning">Next</span></template>
      <template #last-text><span class="text-info">Last</span></template>
      <template #ellipsis-text>
        <b-spinner small type="grow"></b-spinner>
        <b-spinner small type="grow"></b-spinner>
        <b-spinner small type="grow"></b-spinner>
      </template>
      <template #page="{ page, active }">
        <b v-if="active">{{ page }}</b>
        <i v-else>{{ page }}</i>
      </template>
    </b-pagination-nav>
  </div>
</template>

<!-- b-pagination-nav-appearance.vue -->

The slot page is always scoped, while the slots first-text, prev-text, next-text and last-text are optionally scoped. The ellipsis-text slot is not scoped.

Scoped variables properties available to the page slot:

Property Type Description
page Number Page number (from 1 to numberOfPages)
index Number Page number (indexed from 0 to numberOfPages -1)
active Boolean If the page is the active page
disabled Boolean If the page button is disabled
content String default content, or the result of the page-gen function

Scoped variables properties available to the first-text, prev-text, next-text and last-text slots:

Property Type Description
page Number Page number (from 1 to numberOfPages)
index Number Page number (indexed from 0 to numberOfPages -1)
disabled Boolean If the page button is disabled

Goto first/last button type

If you prefer to have buttons with the first and last page number to go to the corresponding page, use the first-number and last-number props.

<template>
  <div class="overflow-auto">
    <div>
      <h6>Goto first button number</h6>
      <b-pagination-nav
        v-model="currentPage"
        :number-of-pages="pages"
        base-url="#"
        first-number
      ></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Goto last button number</h6>
      <b-pagination-nav
        v-model="currentPage"
        :number-of-pages="pages"
        base-url="#"
        last-number
      ></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Goto first and last button number</h6>
      <b-pagination-nav
        v-model="currentPage"
        :number-of-pages="pages"
        base-url="#"
        first-number
        last-number
      ></b-pagination-nav>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        pages: 100,
        currentPage: 5
      }
    }
  }
</script>

<!-- b-pagination-nav-goto-first-last-number.vue -->

Button size

Optionally change from the default button size by setting the size prop to either 'sm' for smaller buttons or 'lg' for larger buttons.

<template>
  <div class="overflow-auto">
    <div>
      <h6>Small</h6>
      <b-pagination-nav size="sm" number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Default</h6>
      <b-pagination-nav number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Large</h6>
      <b-pagination-nav size="lg" number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>
  </div>
</template>

<!-- b-pagination-nav-size.vue -->

Pill style

Easily switch to pill style buttons by setting the pills prop

<template>
  <div class="overflow-auto">
    <div>
      <h6>Small Pills</h6>
      <b-pagination-nav pills size="sm" number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Default Pills</h6>
      <b-pagination-nav pills number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6>Large Pills</h6>
      <b-pagination-nav pills size="lg" number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>
  </div>
</template>

<!-- b-pagination-nav-pills.vue -->

Note: Pill styling requires BootstrapVue's custom CSS/SCSS.

Alignment

By default the pagination component is left aligned. Change the alignment to center, right (right is an alias for end), or 'fill' by setting the prop align to the appropriate value.

<template>
  <div class="overflow-auto">
    <div>
      <h6>Left alignment (default)</h6>
      <b-pagination-nav number-of-pages="10" base-url="#"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6 class="text-center">Center alignment</h6>
      <b-pagination-nav number-of-pages="10" base-url="#" align="center"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6 class="text-right">Right (end) alignment</h6>
      <b-pagination-nav number-of-pages="10" base-url="#" align="right"></b-pagination-nav>
    </div>

    <div class="mt-3">
      <h6 class="text-center">Fill alignment</h6>
      <b-pagination-nav number-of-pages="10" base-url="#" align="fill"></b-pagination-nav>
    </div>
  </div>
</template>

<!-- b-pagination-nav-alignment.vue -->

Auto current page detection and v-model support

<b-pagination-nav> will try and automatically detect which page button should be active, based on the page's current URL or $route (if a router is detected). In cases where it cannot detect the page, no page number buttons will be in the active state, and the first, previous, next and last buttons will be in the disabled state until a page button is clicked.

v-model is optionally supported (updated by the input event, and tied to the value prop). Setting the v-model to null (the default) initially will trigger auto active page detection, and will subsequently be updated with the current page number (indexed from 1 to number of pages). If you initially set the v-model to a value of 1 or greater, auto page detection will not occur (until after a user clicks a page button), and the page specified by the v-model will be set as active.

To disable auto active page detection, set the no-page-detect prop to true.

Note: Auto page detection needs to loop through all possible page links until a match is detected. For larger number-of-pages, this check can take some time so you may want to manually control which page is the active via the v-model and the no-page-detect prop.

Preventing a page from being selected

You can listen for the page-click event, which provides an option to prevent the page from being selected. The event is emitted with two arguments:

  • bvEvent: The BvEvent object. Call bvEvent.preventDefault() to cancel page selection
  • page: Page number to select (starting with 1)

For accessibility reasons, when using the page-click event to prevent a page from being selected, you should provide some means of notification to the user as to why the page is not able to be selected. It is recommended to use the disabled attribute on the <b-pagination-nav> component instead of using the page-click event (as disabled is more intuitive for screen reader users).

Accessibility

The <b-pagination-nav> component provides many features to support assistive technology users, such as aria- attributes and keyboard navigation.

ARIA labels

<b-pagination-nav> provides various *-label-* props which are used to set the aria-label attributes on the various elements within the component, which will help users of assistive technology.

Prop aria-label content default
label-first-page "Goto first page"
label-prev-page "Goto previous page"
label-next-page "Goto next page"
label-last-page "Goto last page"
label-page "Goto page", appended with the page number
aria-label "Pagination", applied to the outer pagination container

The label-page will optionally accept a function to generate the aria-label. The function is passed a single argument which is the page number (indexed from 1 to number of pages).

You can remove any label by setting the prop to an empty string (''), although this is not recommended unless the content of the button textually conveys its purpose.

Keyboard navigation

<b-pagination-nav> supports standard Tab key navigation.

See also

Refer to the Router support reference page for router-link specific props.

For pagination control of a component (such as <b-table>) or a pagination list, use the <b-pagination> component instead.

Component reference

<b-pagination-nav>

Properties

All property default values are globally configurable.

Property
(Click to sort ascending)
Type
(Click to sort ascending)
Default
Description
active
BooleanfalseWhen set to `true`, places the component in the active state with active styling
active-class
String<router-link> prop: Configure the active CSS class applied when the link is active. Typically you will want to set this to class name 'active'
align
String'left'Alignment of the page buttons: 'start' (or 'left'), 'center', 'end' (or 'right'), or 'fill'
append
Booleanfalse<router-link> prop: Setting append prop always appends the relative path to the current path
aria-label
String'Pagination'Value to place in the 'aria-label' attribute of the pagination control
base-url
String'/'Base URL to use when auto generating page links
disabled
BooleanfalseWhen set to `true`, disables the component's functionality and places it in a disabled state
ellipsis-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'ellipsis' placeholders
ellipsis-text
String'…'Content to place in the ellipsis placeholder
exact
Booleanfalse<router-link> prop: The default active class matching behavior is inclusive match. Setting this prop forces the mode to exactly match the route
exact-active-class
String<router-link> prop: Configure the active CSS class applied when the link is active with exact match. Typically you will want to set this to class name 'active'
exact-path
Booleanfalse<router-link> prop: Allows matching only using the path section of the url, effectively ignoring the query and the hash sections
exact-path-active-class
String<router-link> prop: Configure the active CSS class applied when the link is active with exact path match. Typically you will want to set this to class name 'active'
first-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'Go to first page' button
first-number
v2.3.0+
BooleanfalseDisplay first page number instead of Goto First button
first-text
String'«'Content to place in the goto first page button
hide-ellipsis
BooleanfalseDo not show ellipsis buttons
hide-goto-end-buttons
BooleanfalseHides the goto first and goto last page buttons
href
String<b-link> prop: Denotes the target URL of the link for standard a links
label-first-page
String'Go to first page'Value to place in the 'aria-label' attribute of the goto first page button
label-last-page
String'Go to last page'Value to place in the 'aria-label' attribute of the goto last page button
label-next-page
String'Go to next page'Value to place in the 'aria-label' attribute of the goto next page button
label-page
Function or String'Go to page'Value to place in the 'aria-label' attribute of the goto page button. Page number will be prepended automatically
label-prev-page
String'Go to previous page'Value to place in the 'aria-label' attribute of the goto previous page button
last-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'Go to last page' button
last-number
v2.3.0+
BooleanfalseDisplay last page number instead of Goto Last button
last-text
String'»'Content to place in the goto last page button
limit
Number or String5Maximum number of buttons to show (including ellipsis if shown, but excluding the bookend buttons)
link-gen
FunctionLink generator function. See docs for details
next-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'Go to next page' button
next-text
String'›'Content to place in the goto next page button
no-page-detect
BooleanfalseDisable of auto detection of current page
no-prefetch
Booleanfalse<nuxt-link> prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting `no-prefetch` will disabled this feature for the specific link
number-of-pages
Number or String1Total number of pages
page-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'Go to page #' buttons
page-gen
FunctionPage number generator function. See docs for details
pages
ArrayArray of page numbers and links
pills
v2.1.0+
BooleanfalseApplies pill styling to the pagination buttons
prefetch
v2.15.0+
Booleannull<nuxt-link> prop: To improve the responsiveness of your Nuxt.js applications, when the link will be displayed within the viewport, Nuxt.js will automatically prefetch the code splitted page. Setting `prefetch` to `true` or `false` will overwrite the default value of `router.prefetchLinks`
prev-class
v2.3.0+
Array or Object or StringClass(es) to apply to the 'Go to previous page' button
prev-text
String'‹'Content to place in the goto previous page button
rel
Stringnull<b-link> prop: Sets the `rel` attribute on the rendered link
replace
Booleanfalse<router-link> prop: Setting the replace prop will call `router.replace()` instead of `router.push()` when clicked, so the navigation will not leave a history record
router-component-name
v2.15.0+
String<b-link> prop: BootstrapVue auto detects between `<router-link>` and `<nuxt-link>`. In cases where you want to use a 3rd party link component based on `<router-link>`, set this prop to the component name. e.g. set it to 'g-link' if you are using Gridsome (note only `<router-link>` specific props are passed to the component)
size
StringSize of the rendered buttons: 'sm', 'md' (default), or 'lg'
target
String'_self'<b-link> prop: Sets the `target` attribute on the rendered link
to
Object or String<router-link> prop: Denotes the target route of the link. When clicked, the value of the to prop will be passed to `router.push()` internally, so the value can be either a string or a Location descriptor object
use-router
BooleanfalseRender router-links instead of links when auto generating the page links
value
v-model
Boolean or Number or StringnullCurrent page number, starting from 1

<b-pagination-nav> supports generating <router-link> or <nuxt-link> component (if using Nuxt.js). For more details on the router link (or nuxt link) specific props, see the Router support reference section.

v-model

Property
Event
valueinput

Slots

Name
Scoped
Description
ellipsis-text NoThe '...' indicator content. Not scoped
first-text The "go to first page" button content. Optionally scoped
last-text The "go to last page" button content. Optionally scoped
next-text The "go to next page" button content. Optionally scoped
page Page number button content. Always scoped
prev-text The "go to previous page" button content. Optionally scoped

Events

Event
Arguments
Description
change
  1. page - Selected page number (starting with `1`)
Emitted when page changes via user interaction
input
  1. page - Selected page number (starting with `1`), or `null` if no page found
Emitted when page changes via user interaction or programmatically
page-click v2.17.0+
  1. bvEvent - The `BvEvent` object. Call `bvEvent.preventDefault()` to cancel page selection
  2. page - Page number to select (starting with `1`)
Emitted when a page button was clicked. Cancelable

Importing individual components

You can import individual components into your project via the following named exports:

Component
Named Export
Import Path
<b-pagination-nav>BPaginationNavbootstrap-vue

Example:

import { BPaginationNav } from 'bootstrap-vue'
Vue.component('b-pagination-nav', BPaginationNav)

Importing as a Vue.js plugin

This plugin includes all of the above listed individual components. Plugins also include any component aliases.

Named Export
Import Path
PaginationNavPluginbootstrap-vue

Example:

import { PaginationNavPlugin } from 'bootstrap-vue'
Vue.use(PaginationNavPlugin)