Skip to content
lab components / Navigation

Pagination

Enable users to navigate efficiently through large datasets or content spanning multiple pages. Allow customization of the number of items displayed per page.

This is a Lab component!

That means it doesn't satisfy our definition of done and may be changed or even deleted. For an exact status, please reach out to the Fancy team through the dev_fancy or ux_fancy channels.

import { Pagination } from "@siteimprove/fancylab";

#Examples

Pagination is a crucial navigation element for large datasets or lengthy content. It breaks information into manageable chunks, preventing overwhelm and improving the user experience.

Pagination is composed of

  • Total item count: Clearly show the range of currently visible items (e.g., "1-10 of 100").
  • Navigation controls:
    • Previous/Next buttons: Use clear icons (e.g., chevrons) or text labels.
    • First/Last buttons (optional): Include for large datasets to enable quick navigation.
    • Page number information and input field (optional): Display the current page and allow direct input for specific pages (e.g., "Page 3 of 10").
  • Items per page (optional): Allow users to adjust the number of items displayed per page.
1 - 5 of 1000 items
const [page, setPage] = useState(1); const [pageSize, setPageSize] = useState(5); const allData = Array.from(Array(1000).keys()); const pagedData = allData.slice((page - 1) * pageSize, page * pageSize); return ( <Pagination count={pagedData.length} total={allData.length} page={page} setPage={setPage} pageSize={pageSize} setPageSize={setPageSize} cancelLabel="Cancel" confirmLabel="Confirm" firstLabel="First" prevLabel="Previous" nextLabel="Next" lastLabel="Last" pagingInfoLabel={(startIdx: number, endIdx: number, total: number) => `${startIdx} - ${endIdx} of ${total} items` } pageLabel="Page" pageXofYLabel={(current: number, total: number) => `Page ${current} of ${total}`} pageSizeSelectionLabel={(pageSize: number) => `${pageSize} items`} pageSizeSelectorPrefix="Show" pageSizeSelectorPostfix="per page" pageSizeLabel="Items per page" defaultError="Default pagination error" wholeNumberError="Must be a whole number" outOfBoundsError={(total: number) => `Enter a number between 1 and ${total}`} ariaLabel="Pagination" /> );

#Properties

1 - 5 of 25 items
PropertyDescriptionDefinedValue
totalRequired
numberTotal count of items
pageRequired
numberSelected page number
setPageRequired
functionCallback to change the selected page
pageSizeRequired
numberSelected page size
setPageSizeRequired
| functionCallback to change the selected page size
cancelLabelRequired
stringLabel for the cancel button
confirmLabelRequired
stringLabel for the confirm button
firstLabelRequired
stringTooltip text for the first button
prevLabelRequired
stringTooltip text for the previous button
nextLabelRequired
stringTooltip text for the next button
lastLabelRequired
stringTooltip text for the last button
pagingInfoLabelRequired
functionLabel for paging info - something like `${startIdx} - ${endIdx} of ${total} items`
pageLabelRequired
stringLabel for page input
pageXofYLabelRequired
functionLabel for page dropdown button - something like `Page ${current} of ${total}
pageSizeSelectionLabelRequired
functionLabel for pageSize dropdown button - something like `${pageSize} items`
pageSizeSelectorPrefixRequired
stringLabel before pageSize changer - Show (<- this part) DROPDOWN per page
pageSizeSelectorPostfixRequired
stringLabel after pageSize changer - Show DROPDOWN per page (<- this part)
pageSizeLabelRequired
stringLabel for pageSize radios - something like "Items per page"
defaultErrorRequired
stringDefault error for page number input
wholeNumberErrorRequired
stringError for page number input when number is not integer
outOfBoundsErrorRequired
functionError for page number input when number is out of bounds (below 1 and above total)
countOptional
numberCount of items
loadingOptional
booleanLoading state
observeKeyPrefixOptional
stringUsed as data observe key for pagination buttons
ariaLabelOptional
stringText for the ARIA label

#Guidelines

#Best practices

#General

Use Pagination when

  • The amount of information exceeds a single page's comfortable display capacity.
  • Users need to locate specific items within a larger collection.
  • You want to enhance the perceived loading speed of a page by breaking it into smaller chunks.

#Placement

Pagination is typically used in the following places:

  • Below content: The most common and intuitive location.
  • Within Data Tables/Lists: Enhance navigation within structured data.
  • Search results: Facilitate browsing through multiple pages of results.

#Style

  • Siteimprove Design System: Adhere to Siteimprove's guidelines for color, typography, and spacing. If you are not using a component from Fancy, match the styling of your Pagination to existing components for visual consistency.
  • Loading states: Use visual cues (e.g., Spinner) to indicate when pages are loading.
  • Empty states: Display a friendly message when no results are found on a page (e.g., "No results found for this page.").
  • Error states: If pagination fails, provide a clear error message (e.g Toast) and offer solutions (e.g., "An error occurred while loading this page. Please try again later.").
  • Items per page: Provide reasonable default options based on content type.

#Do not use when

  • The dataset is small enough to fit on one page.
  • The content is best presented as infinite scrolling.

#Accessibility

#For designers

  • Ensure sufficient contrast between text/icons and background.

#For developers

This component comes with built-in accessibility, no extra work required.

Explore detailed guidelines for this component: Accessibility Specifications

#Writing

#Labels

  • Use "Previous" and "Next" for basic navigation.
  • Consider "First" and "Last" for larger datasets.
  • Avoid ambiguous terms like "More" or "Load More."

#Page Numbers

  • Clearly indicate the current page.
  • Allow direct input for specific page numbers in large datasets.