Skip to main content
Variations

The pagination parent provides layout and configuration for its subcomponents: Page navigator, Page sizer, and Page dialer.

<bolt-pagination total="10">
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>

Navigator and Dialer share the same values for current page and total pages, and these may be configured together on the parent.

<bolt-pagination currentpage="7" total="10">
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>

Sizer's current size can also be configured at the parent level, allowing the parent to handle all values that may need updated based on user interaction.

<bolt-pagination total="10" currentsize="25">
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>

If necessary, these properties can be configured directly on each subcomponent, but passthrough configurations on the parent will override them.

Typically all 3 Pagination subcomponents should be used together, but other combinations are permitted.

<bolt-pagination total="10">
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>
<bolt-pagination total="10">
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
</bolt-pagination>
<bolt-pagination total="10">
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>

The page navigator primarily enables relative navigation from the current page.

Specifically, it enables navigation to the following:

  • First page
  • Previous page
  • Adjacent pages
  • Next page
  • Last page

Set the total parameter of the navigator to the total number of pages in your data.

If left unconfigured, the navigator assumes that the total number of pages is unknown and will automatically adjust its appearance to reflect the assumption.

<bolt-page-navigator
  total="10"
></bolt-page-navigator>

Set the current parameter of the navigator to reflect the current page of data.

<bolt-page-navigator
  current="5"
  total="10"
></bolt-page-navigator>
<bolt-page-navigator
  current="10"
  total="10"
></bolt-page-navigator>

The spread parameter of the navigator configures the maximum number of pages to display between the "previous" and "next" links. This can help reduce the navigator's size in the UI.

<bolt-page-navigator
  spread="3"
  total="10"
></bolt-page-navigator>

If there aren't enough pages to fill the spread, the navigator will display as many links as possible.

<bolt-page-navigator
  spread="5"
  total="2"
></bolt-page-navigator>

To help reduce the navigator's size, you can hide the "First" and "Last" links by including the [nofirstlast] attribute.

<bolt-page-navigator
  nofirstlast
  total="10"
></bolt-page-navigator>

You may encounter scenarios where the total number of pages is either frequently changing or unknown. However, it may still be possible to navigate one page at a time.

In these scenarios:

  1. leave the total parameter unconfigured
  2. leave the spread parameter unconfigured

The navigator will automatically adjust to this scenario by doing the following:

  • disable the "Last" link
  • lock the spread to 1
<bolt-page-navigator
  current="1"
></bolt-page-navigator>
<bolt-page-navigator
  current="4"
></bolt-page-navigator>

When total pages is unknown and it is no longer possible to navigate forward, you can disable the "next" link by adding the [disablenext] attribute to the navigator.

The disablenext parameter has no affect when total is known.

<bolt-page-navigator
  current="7"
  disablenext
></bolt-page-navigator>

The page sizer provides a control for selecting how many items to display per page.

<bolt-page-sizer></bolt-page-sizer>
<bolt-page-sizer
  label="Results per page"
></bolt-page-sizer>

Set the options parameter of the sizer to define which item counts should be available for selection.

Options are displayed in ascending order.

<bolt-page-sizer
  options="[25,50,100]"
></bolt-page-sizer>

Set the current parameter of the sizer to control the currently selected option.

<bolt-page-sizer
  current="50"
></bolt-page-sizer>

The page dialer provides a direct way to navigate to a specific page number by entering a value within the total number of pages.

Set the total parameter of the dialer to the total number of pages in your data.

<bolt-page-dialer
  total="25"
></bolt-page-dialer>

Set the current parameter of the dialer to reflect the current page of data.

<bolt-page-dialer
  current="7"
  total="25"
></bolt-page-dialer>
Code reference

Pagination does not manage data fetching or business logic. It is purely an interface for downstream projects to connect their own business logic.

Please refer to pagination events for more information on how to wire up your business logic.

The pagination parent component provides passthrough configuration for a few key attributes of its subcomponents.

  • total (required conditionally)
    • Sets total attribute on Navigator and Dialer
    • Required when Dialer is present, but may be set at either parent or subcomponent level
  • currentpage (optional)
    • Sets current attribute on Navigator and Dialer
  • currentsize (optional)
    • Sets current attribute on Sizer

While current and total can also be set directly on the individual subcomponents, be aware that configuration on the parent will override these attributes, and avoid setting them at multiple levels.

<bolt-pagination total="4" currentpage="2" currentsize="25">
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
</bolt-pagination>
<bolt-pagination>
  <bolt-page-navigator slot="navigator" 
    current="2" 
    total="4"
  ></bolt-page-navigator>
  <bolt-page-dialer slot="dialer" 
    current="2" 
    total="4"
  ></bolt-page-dialer>
  <bolt-page-sizer slot="sizer" 
    current="25"
  ></bolt-page-sizer>
</bolt-pagination>

Additional parameters are available on the individual slotted components. Please refer to the "Parameters" section for each subcomponent below for the full list of configurable options.

  • bolt-pagination-change
    • Emitted when the current page or page size changes due to user interaction
    • The event provides the following detail data:
      • type: Specifies whether the event represents a page ("page") or page size (items per page) change ("size")
      • value: the target page number to navigate to, or the updated count of items per page, depending on type
<bolt-pagination 
  id="pagination"
  total="20"
>
  <bolt-page-sizer slot="sizer"></bolt-page-sizer>
  <bolt-page-navigator slot="navigator"></bolt-page-navigator>
  <bolt-page-dialer slot="dialer"></bolt-page-dialer>
</bolt-pagination>

<script type="module">
  const boltPagination = document.querySelector('#pagination');

  boltPagination.addEventListener('bolt-pagination-change', (event) => {
    let newValue = event.detail.value

    // call custom business logic to update displayed data
    if(event.detail.type === 'page') {
      await updateData({ page: newValue })
    }

    if(event.detail.type === 'size') {
      await updateItemsOnPage({ count: newValue });
    }
  });
</script>

The navigator is not responsible for performing navigation logic. It is purely an interface for downstream projects to connect their own navigation business logic.

Please refer to navigator events for more information on how to wire up your business logic.

diagram of elements that make up the bolt-page-navigator custom element

  • First
    • Click to navigate to page 1 of data
  • Previous
    • Click to navigate back by 1 page
  • Page span
    • Links to adjacent pages
    • Current is not clickable, but indicates active page number
  • Next
    • Click to navigate forward by 1 page
  • Last
    • Click to navigate to last page of data
  • current (optional)
    • Current page number
    • Type: number
    • Default: 1
    • Values: 1 ≤ current ≤ total
  • disablenext (optional)
    • When true, disables the "Next" button.
      • Only applies when total is unknown.
    • Type: boolean
    • Default: false
  • nofirstlast (optional)
    • When true, hides the "First" and "Last" buttons.
    • Type: boolean
    • Default: false
  • spread (optional)
    • Maximum number of page links to display.
      • In some configurations, the resolved value may be less than the configured value.
    • Type: number
    • Default: 5
    • Values: 1 ≤ spread ≤ 5
  • total (optional)
    • Total number of pages
    • Various configurations may be limited if this value is not finite.
    • Type: number
    • Default: Infinity (a.k.a., "unknown")
    • Values: 1 ≤ total < Infinity
  • bolt-goto
    • Emitted when an active link is clicked
    • The event provides the following detail data:
      • page: the target page number that should be navigated to
<bolt-page-navigator
  id="pageNav"
  total="10"
></bolt-page-navigator>
<script type="module">
  const boltPageNavigator = document.querySelector('#pageNav')

  boltPageNavigator.addEventListener('bolt-goto', async (event) => {
    let newPage = event.detail.page

    // call custom business logic to update displayed data
    await updateData({ page: newPage })
  })
</script>

The sizer is not responsible for performing pagination or data-fetching logic. It is purely an interface for downstream projects to connect their own business logic for handling page size changes.

Please refer to sizer events for more information on how to wire up your business logic.

  • options (optional)
    • Available item counts for selection
    • Type: array<number>
    • Default: [10,25,50]
    • Values: 2-3 unique, positive integers (1 ≤ N)
  • current (optional)
    • Currently selected item count
    • Type: number
    • Default: The smallest value in options
    • Values: 1 ≤ current ≤ largest value in options
  • label (optional)
    • Text displayed before the options group
    • Type: string
    • Default: "Items per page"
  • bolt-sizer-update
    • Emitted when an active option is clicked
    • The event provides the following detail data:
      • count: the updated count of items per page
<bolt-page-sizer
  id="pageSizer"
></bolt-page-sizer>
<script type="module">
  const boltPageSizer = document.querySelector('#pageSizer')

  boltPageSizer.addEventListener('bolt-sizer-update', async (event) => {
    let newCount = event.detail.count

    // call custom business logic to update displayed data
    await updateItemsOnPage({ count: newCount })
  })
</script>

The dialer is not responsible for performing pagination or data-fetching logic. It is purely an interface for downstream projects to connect their own navigation business logic.

Please refer to dialer events for more information on how to wire up your business logic.

  • total
    • Total number of pages
    • Type: number
    • Values: ≥ 1
  • current (optional)
    • Current page number
    • Type: number
    • Default: 1
    • Values: 1 ≤ current ≤ total
  • bolt-goto
    • Emitted when the user submits a valid page number. This event can be triggered by pressing the Enter key while the input is focused, or the submit button.
    • The event provides the following detail data:
      • page: the target page number that should be navigated to
<bolt-page-dialer
  id="pageDialer"
  total="25"
></bolt-page-dialer>
<script type="module">
  const boltPageDialer = document.querySelector('#pageDialer')

  boltPageDialer.addEventListener('bolt-goto', async (event) => {
    let newPage = event.detail.page

    // call custom business logic to update displayed data
    await updateData({ page: newPage })
  })
</script>
Design guidelines
  • Pagination helps to make large amounts of information more manageable and easier to navigate. It improves a user’s experience by preventing information overload and making navigation more intuitive.
  • Pagination is made up of 3 parts: Page navigator, Page sizer, and Page dialer.
  • Best practice is to display all available portions of Pagination for the most context.
    • Sometimes, depending on the content or data, one or more of the elements may not be necessary to display.
  • Page navigator should always have Buttons to move to the next or previous page of the dataset and a way to quickly return to the beginning or end of the dataset.
  • It should highlight the page number the user is on currently.
  • Replace the last page number with an ellipsis when the total number of pages is unknown.
  • Avoid the Page navigator if you need to navigate directly to any valid page number.
    • The Page dialer is better suited for this interaction.
  • Page sizer allows users to change the amount of data displayed.
  • The Page sizer should be used to configure the maximum number of items to display in a single page of data.
  • All options should be available at all times, even if an option is greater than then number of results. For example, if the Page sizer options are 10, 20, and 100, but there are only 40 possible results, the user should still be able to click on 100.
  • Page dialer allows the user to navigate directly to any valid page.
  • When the total number of pages is known, the last page number should display as text within the field so that users know a valid range to input.
  • Avoid if needing to navigate relative to the current page.
  • Use to divide large quantities of data or content into digestible amounts.
  • Consider Pagination when a list or dataset has more than 25 items.
  • Use to improve the loading performance of a system.
  • Use to enable all users to navigate through pages of data or locate a specific page number.
  • Use the Page navigator when needing to navigate relative to the current page (e.g., next page, previous page, etc.).
  • Use the Page dialer if needing to navigate directly to any valid page number.
  • Avoid if there are only a few items in a dataset.
  • Avoid if content is being lazy loaded as the user scrolls.
  • Avoid if desiring to switch between slides or content in a carousel.
  • Consider using navigation instead of Pagination if content is not part of the same dataset.
  • When navigating between steps in a flow, use Button Bar.
  • Use lazy loading instead of Pagination for loading content as the user scrolls.
  • Use an alternative method for switching between slides or content in a carousel.
  • If the data set is small, display content on a single page instead of using Pagination.

Do

  • Center-align Pagination to its parent container.
  • Identify the current page to provide awareness of location.
  • Display at least one way for users to navigate through pages.
  • Display additional details (number of pages and total number of items).
  • Paginate content that would be easier to browse when segmented.
  • Place Pagination at the bottom of the content being paginated.

Don't

  • Don't loop Pagination.
  • Don't disable page numbers.
  • Don't skip over numbers within the range.
  • Don't use Pagination when content is not part of the same set.
  • Don't use numbered Pagination for switching between slides or content in a carousel.
  • Don't add additional editorial content.
Accessibility
  • WCAG 2.2 Compliant
  • JAWS 2025 Tested
  • NVDA 2025 Tested
  • VoiceOver Tested
  • Keyboard Tested
  • aXe Tested
  • When the current page is displayed (e.g., page 1 when on page 1), it should not be presented as a link and is therefore not focusable. However, screen readers can still read it using arrow keys to ensure users are informed about their current position in Pagination.
  • Disabled links should be hidden from screen readers to avoid confusion or unnecessary interaction.
  • Pressing Tab follows a focus order progression based on what page the user is currently on:
    • When on the first page, focus should start on the next link forward from the current page (e.g., focus is on the page 2 link when on page 1) then move to subsequent page links, followed by the "Next" and "Last" links (if available). "First" and "Previous" links should be disabled in this case.
    • When on any page that is not the first or last page, focus should start on the "First" or "Previous" link (if available), then move into the page links, and finally the "Next" and "Last" links (if available).
    • When on the last page, focus should start on the "First" or "Previous" link (if available), then moves into the page links. "Next" and "Last" links should be disabled.
    • At the end of Pagination, focus should cycle to the next interactive element outside of Pagination.

tab order on pagination component

All Bolt components have gone through accessibility testing, but please keep our accessibility guidelines in mind.

Display settings

Note: not all settings persist across pages

Default Compact (-1) Sparse (+1) XL (default) 2XL 3XL Default Min Max Light (default) System Dark Branded (default) Unbranded