Examples › Pagination

You can enable pagination by setting the following Mantine DataTable properties:

  • page: number
    The current page number.
  • onPageChange
    A callback that is executed when the user changes the current page.
  • totalRecords: number
    The total number of records in the dataset.
  • recordsPerPage: number
    The number of records per page.
First name
Last name
Email
Birth date
JeraldHowellJerald.Howell32@yahoo.comMay 21 1950
KathleenRueckerKathleen_Ruecker@hotmail.comDec 19 1943
EricaVolkmanErica.Volkman37@gmail.comJan 29 1955
CliffordOberbrunnerClifford.Oberbrunner@hotmail.comMar 6 1979
AlisonKlingAlison16@gmail.comJan 27 1997
SueZiemeSue.Zieme29@hotmail.comSep 12 1960
FeliciaGleasonFelicia30@yahoo.comMar 9 1977
AlfredoZemlakAlfredo22@yahoo.comNov 12 1988
EmilyBartolettiEmily.Bartoletti@gmail.comJan 5 1968
DeloresReynoldsDelores.Reynolds@yahoo.comJun 4 2004
LouisSchambergerLouis6@yahoo.comSep 7 1994
BeverlyHellerBeverly_Heller@gmail.comNov 29 2001
EugeneFeestEugene88@hotmail.comFeb 20 1954
MartinBahringerMartin_Bahringer10@gmail.comMay 26 1945
EllisMillerEllis36@hotmail.comMay 24 1950
1 - 15 / 500
No records

If you’re not happy with the default pagination behavior, you can override it by setting these optional properties:

  • loadingText: string
    A text to display while loading records.
  • noRecordsText: string
    A text to display when no records are present.
  • paginationText
    A callback receiving an object in the shape of { from: number; to: number; totalRecords: number } and returning a ReactNode representing the pagination text.
  • paginationSize: 'xs' | 'sm' | 'md' | 'lg' | 'xl'
    The pagination size.
  • paginationWrapBreakpoint: 'xs' | 'sm' | 'md' | 'lg' | 'xl' | (string & {}) | number
    A breakpoint below which the pagination footer content will wrap on multiple lines. Defaults to sm.
    You can also provide a string like '300px' or '20rem', or a number, in which case it will be interpreted as a pixel value and converted to rem value before being applied.
  • paginationActiveTextColor: MantineColor | { light: MantineColor; dark: MantineColor }
    Color applied to active page button text.
    Can be a MantineColor (key of theme.colors or any valid CSS color string), or an object with light and dark keys and MantineColor values.
    Defaults to white.
  • paginationActiveBackgroundColor: MantineColor | { light: MantineColor; dark: MantineColor }
    Color applied to active page button background.
    Can be a MantineColor (key of theme.colors or any valid CSS color string), or an object with light and dark keys and MantineColor values.
    Defaults to primary theme color.

Here is the code:

'use client';

import { DataTable } from 'mantine-datatable';
import dayjs from 'dayjs';
import { useEffect, useState } from 'react';
import employees from '~/data/employees.json';

const PAGE_SIZE = 15;

export default function PaginationExample() {
  const [page, setPage] = useState(1);
  const [records, setRecords] = useState(employees.slice(0, PAGE_SIZE));

  useEffect(() => {
    const from = (page - 1) * PAGE_SIZE;
    const to = from + PAGE_SIZE;
    setRecords(employees.slice(from, to));
  }, [page]);

  return (
    <DataTable
      height={300}
      withTableBorder
      records={records}
      columns={[
        { accessor: 'firstName', width: 100 },
        { accessor: 'lastName', width: 100 },
        { accessor: 'email', width: '100%' },
        {
          accessor: 'birthDate',
          textAlign: 'right',
          width: 120,
          render: ({ birthDate }) => dayjs(birthDate).format('MMM D YYYY'),
        },
      ]}
      totalRecords={employees.length}
      recordsPerPage={PAGE_SIZE}
      page={page}
      onPageChange={(p) => setPage(p)}
      // 👇 uncomment the next line to use a custom pagination size
      // paginationSize="md"
      // 👇 uncomment the next line to use a custom loading text
      // loadingText="Loading..."
      // 👇 uncomment the next line to display a custom text when no records were found
      // noRecordsText="No records found"
      // 👇 uncomment the next line to use a custom pagination text
      // paginationText={({ from, to, totalRecords }) => `Records ${from} - ${to} of ${totalRecords}`}
      // 👇 uncomment the next lines to use custom pagination colors
      // paginationActiveBackgroundColor="green"
      // paginationActiveTextColor="#e6e348"
    />
  );
}

Displaying a page size selector

You can display a selector to let the user choose the page size by setting the following component properties:

  • recordsPerPageOptions: number[]
    An array of page size numbers to display in the page size selector.
  • onRecordsPerPageChange
    A callback that is executed when the user changes the page size. Receives the new page size as its argument.
  • recordsPerPageLabel
    The page size selector label, defaulting to 'Records per page'.
'use client';

import { DataTable } from 'mantine-datatable';
import dayjs from 'dayjs';
import { useEffect, useState } from 'react';
import employees from '~/data/employees.json';

const PAGE_SIZES = [10, 15, 20];

export default function PaginationExampleWithPageSizeSelector() {
  const [pageSize, setPageSize] = useState(PAGE_SIZES[1]);

  useEffect(() => {
    setPage(1);
  }, [pageSize]);

  const [page, setPage] = useState(1);
  const [records, setRecords] = useState(employees.slice(0, pageSize));

  useEffect(() => {
    const from = (page - 1) * pageSize;
    const to = from + pageSize;
    setRecords(employees.slice(from, to));
  }, [page, pageSize]);

  return (
    <DataTable
      withTableBorder
      records={records}
      columns={[
        { accessor: 'firstName', width: 100 },
        { accessor: 'lastName', width: 100 },
        { accessor: 'email', width: '100%' },
        {
          accessor: 'birthDate',
          textAlign: 'right',
          width: 120,
          render: ({ birthDate }) => dayjs(birthDate).format('MMM D YYYY'),
        },
      ]}
      totalRecords={employees.length}
      paginationActiveBackgroundColor="grape"
      recordsPerPage={pageSize}
      page={page}
      onPageChange={(p) => setPage(p)}
      recordsPerPageOptions={PAGE_SIZES}
      onRecordsPerPageChange={setPageSize}
    />
  );
}
First name
Last name
Email
Birth date
JeraldHowellJerald.Howell32@yahoo.comMay 21 1950
KathleenRueckerKathleen_Ruecker@hotmail.comDec 19 1943
EricaVolkmanErica.Volkman37@gmail.comJan 29 1955
CliffordOberbrunnerClifford.Oberbrunner@hotmail.comMar 6 1979
AlisonKlingAlison16@gmail.comJan 27 1997
SueZiemeSue.Zieme29@hotmail.comSep 12 1960
FeliciaGleasonFelicia30@yahoo.comMar 9 1977
AlfredoZemlakAlfredo22@yahoo.comNov 12 1988
EmilyBartolettiEmily.Bartoletti@gmail.comJan 5 1968
DeloresReynoldsDelores.Reynolds@yahoo.comJun 4 2004
LouisSchambergerLouis6@yahoo.comSep 7 1994
BeverlyHellerBeverly_Heller@gmail.comNov 29 2001
EugeneFeestEugene88@hotmail.comFeb 20 1954
MartinBahringerMartin_Bahringer10@gmail.comMay 26 1945
EllisMillerEllis36@hotmail.comMay 24 1950
1 - 15 / 500
Records per page
No records

Using pagination control props

You can provide additional props to pagination controls by using the getPaginationControlProps callback. For example, if you’re not happy with the default accessibility aria-labels, you can override them like so:

<DataTable
  // other props...
  getPaginationControlProps={(control) => {
    if (control === 'previous') {
      const title = 'Go to previous page';
      return { title, 'aria-label': title };
    } else if (control === 'next') {
      const title = 'Go to next page';
      return { title, 'aria-label': title };
    }
    return {};
  }}
/>
First name
Last name
Email
Birth date
JeraldHowellJerald.Howell32@yahoo.comMay 21 1950
KathleenRueckerKathleen_Ruecker@hotmail.comDec 19 1943
EricaVolkmanErica.Volkman37@gmail.comJan 29 1955
CliffordOberbrunnerClifford.Oberbrunner@hotmail.comMar 6 1979
AlisonKlingAlison16@gmail.comJan 27 1997
SueZiemeSue.Zieme29@hotmail.comSep 12 1960
FeliciaGleasonFelicia30@yahoo.comMar 9 1977
AlfredoZemlakAlfredo22@yahoo.comNov 12 1988
EmilyBartolettiEmily.Bartoletti@gmail.comJan 5 1968
DeloresReynoldsDelores.Reynolds@yahoo.comJun 4 2004
LouisSchambergerLouis6@yahoo.comSep 7 1994
BeverlyHellerBeverly_Heller@gmail.comNov 29 2001
EugeneFeestEugene88@hotmail.comFeb 20 1954
MartinBahringerMartin_Bahringer10@gmail.comMay 26 1945
EllisMillerEllis36@hotmail.comMay 24 1950
1 - 15 / 500
No records

Head over to the next example to discover more features.