Skip to content
Template Empire
Browse components

Data Pagination

A free controlled data pagination component for tables and result sets in Next.js and React.

Shipment records · 1,248 total

Customise

Code

const [pagination, setPagination] = useState({ page: 4, pageSize: 10 });

<DataPagination
  totalItems={1248}
  page={pagination.page}
  pageSize={pagination.pageSize}
  onChange={setPagination}
  ariaLabel="Shipment result pages"
/>

Data Pagination is a free controlled pagination component for Next.js and React, styled with Tailwind. It shows the visible item range, bounded page buttons, and a page-size selector while your application remains in control of the requested page.

The component reports changes through one callback and never slices or fetches records. Its labelled navigation landmark, polite range status, native controls, boundary states, and wrapping layout keep large result sets clear across screen sizes and assistive settings.

Install

Add the @te registry to your components.json once:

{
  "registries": {
    "@te": "https://templateempire.io/r/{name}.json"
  }
}

Then install the component:

npx shadcn@latest add @te/data-pagination

Usage

import { useState } from "react";
import { DataPagination } from "@/components/data-pagination";

export default function Results() {
  const [pagination, setPagination] = useState({ page: 1, pageSize: 25 });

  return (
    <DataPagination
      totalItems={248}
      page={pagination.page}
      pageSize={pagination.pageSize}
      pageSizeOptions={[10, 25, 50]}
      onChange={setPagination}
      ariaLabel="Search result pages"
    />
  );
}

Props

PropTypeDefaultDescription
totalItemsnumberrequiredTotal records in the full result set; invalid or negative totals are treated as zero.
pagenumberrequiredControlled one-based page; values are clamped to the available page range.
pageSizenumberrequiredControlled number of records per page; invalid values use ten.
pageSizeOptionsnumber[][10, 25, 50, 100]Positive unique choices for the labelled native page-size selector. The current page size is always included.
onChange(change: { page: number; pageSize: number }) => voidrequiredCalled after an explicit page or page-size change. A page-size change resets page to one.
ariaLabelstring"Pagination"Accessible name for the navigation landmark.
classNamestringundefinedAdditional classes merged onto the navigation landmark.

Customisation

The component uses semantic theme tokens for borders, surfaces, text and focus. Add layout classes to the navigation landmark with className, and pass page-size options that suit your result set.

<DataPagination
  totalItems={248}
  page={pagination.page}
  pageSize={pagination.pageSize}
  pageSizeOptions={[10, 25, 50]}
  onChange={setPagination}
  className="mt-8"
/>

Frequently asked questions

Is Data Pagination free for commercial use?
Yes. Data Pagination is MIT licensed, so you can use it in personal and commercial projects without attribution.
Does this component fetch or slice records?
No. It reports the selected page and page size through onChange. Your application decides how to load or display the corresponding records.
Can keyboard and screen reader users operate it?
Yes. It uses a labelled navigation landmark, native buttons and select, a polite range status, and ordinary tab order without arrow-key trapping.

Related components

Want the full page this belongs to?Template Empire builds complete Next.js templates with data interfaces and polished detail throughout. Browse the templates that pair with these free components.Explore Template Empire templates