Docs Sorting, grouping & expanding Sorting Sorting
Sorting is on by default. Click a column header to cycle ascending → descending → unsorted; the header shows the current direction and the column-actions menu offers explicit sort/clear items.
Basic Sorting + client pagination — the default feature set.
ID
First name Sort by First name ascending Last name Sort by Last name ascending Email Sort by Email ascending Role Sort by Role ascending Department Sort by Department ascending Status Sort by Status ascending Salary Sort by Salary ascending Start date Sort by Start date ascending Progress Sort by Progress ascending U-1000 Ava Thompson ava.thompson@example.com Owner Engineering active 22 $45,000 Jan 2, 2023 U-1001 Liam Nguyen liam.nguyen@example.com Admin Marketing inactive 25 $47,137 Jan 13, 2023 U-1002 Noah Silva noah.silva@example.com Editor Design pending 28 $49,274 Jan 24, 2023 U-1003 Emma Carter emma.carter@example.com Viewer Sales active 31 $51,411 Feb 4, 2023 U-1004 Olivia Rossi olivia.rossi@example.com Owner Support inactive 34 $53,548 Feb 15, 2023 U-1005 William Walker william.walker@example.com Admin Engineering pending 37 $55,685 Feb 26, 2023 U-1006 Sophia Patel sophia.patel@example.com Editor Marketing active 40 $57,822 Mar 9, 2023 U-1007 James Muller james.muller@example.com Viewer Design inactive 43 $59,959 Mar 20, 2023 U-1008 Isabella Park isabella.park@example.com Owner Sales pending 46 $62,096 Mar 31, 2023 U-1009 Lucas Reyes lucas.reyes@example.com Admin Support active 49 $64,233 Apr 11, 2023 $4,120,536
Multi-column sorting
Enable enableMultiSort to sort by several columns at once (shift-click headers). An order badge indicates each column's position in the sort.
tsx Copy
const table = useDataTable({
data,
columns,
enableMultiSort: true,
initialState: {
sorting: [
{ id: "department", desc: false },
{ id: "salary", desc: true },
],
},
})
Sorting Multi-column sorting (shift-click) with an order badge.
ID
First name Sort by First name ascending Last name Sort by Last name ascending Email Sort by Email ascending Role Sort by Role ascending Department 1 Sort by Department descending Status Sort by Status ascending Start date Sort by Start date ascending Progress Sort by Progress ascending U-1042 Noah Silva noah.silva@example.com Editor Design active 28 $134,754 Apr 8, 2024 U-1037 Leo Haddad leo.haddad@example.com Admin Design inactive 53 $124,069 Feb 13, 2024 U-1032 Charlotte Chen charlotte.chen@example.com Owner Design pending 38 $113,384 Dec 20, 2023 U-1027 James Muller james.muller@example.com Viewer Design active 23 $102,699 Oct 26, 2023 U-1022 Noah Silva noah.silva@example.com Editor Design inactive 48 $92,014 Sep 1, 2023 U-1017 Leo Haddad leo.haddad@example.com Admin Design pending 33 $81,329 Jul 8, 2023 U-1012 Charlotte Chen charlotte.chen@example.com Owner Design active 58 $70,644 May 14, 2023 U-1007 James Muller james.muller@example.com Viewer Design inactive 43 $59,959 Mar 20, 2023 U-1047 James Muller james.muller@example.com Viewer Design pending 43 $55,439 Jun 2, 2024 U-1002 Noah Silva noah.silva@example.com Editor Design pending 28 $49,274 Jan 24, 2023 $4,120,536
Per-column control
Sorting is standard TanStack, so the usual column knobs apply:
enableSorting: false — disable sorting for a column.
sortDescFirst: true — start from descending (handy for numeric columns).
sortFn — a built-in sort function's name, a comparator, or the name of one of your own from the sortFns option.
tsx Copy
const columns: DataTableColumnDef<Person>[] = [
{ accessorKey: "id", header: "ID", enableSorting: false },
{ accessorKey: "salary", header: "Salary", sortDescFirst: true },
]
To reuse a comparator across columns, register it by name with sortFns:
tsx Copy
const PRIORITY = ["low", "medium", "high"]
const table = useDataTable({
data,
columns: [{ accessorKey: "priority", header: "Priority", sortFn: "byPriority" }],
sortFns: {
byPriority: (rowA, rowB, columnId) =>
PRIORITY.indexOf(rowA.getValue(columnId)) -
PRIORITY.indexOf(rowB.getValue(columnId)),
},
})
Custom sort function Sort roles by rank with a named sort function.
ID
First name Sort by First name ascending Last name Sort by Last name ascending Email Sort by Email ascending Role Sort by Role descending Department Sort by Department ascending Status Sort by Status ascending Salary Sort by Salary ascending Start date Sort by Start date ascending Progress Sort by Progress ascending U-1000 Ava Thompson ava.thompson@example.com Owner Engineering active 22 $45,000 Jan 2, 2023 U-1004 Olivia Rossi olivia.rossi@example.com Owner Support inactive 34 $53,548 Feb 15, 2023 U-1008 Isabella Park isabella.park@example.com Owner Sales pending 46 $62,096 Mar 31, 2023 U-1012 Charlotte Chen charlotte.chen@example.com Owner Design active 58 $70,644 May 14, 2023 U-1016 Harper Dubois harper.dubois@example.com Owner Marketing inactive 30 $79,192 Jun 27, 2023 U-1020 Ava Thompson ava.thompson@example.com Owner Engineering pending 42 $87,740 Aug 10, 2023 U-1024 Olivia Rossi olivia.rossi@example.com Owner Support active 54 $96,288 Sep 23, 2023 U-1028 Isabella Park isabella.park@example.com Owner Sales inactive 26 $104,836 Nov 6, 2023 U-1032 Charlotte Chen charlotte.chen@example.com Owner Design pending 38 $113,384 Dec 20, 2023 U-1036 Harper Dubois harper.dubois@example.com Owner Marketing active 50 $121,932 Feb 2, 2024 $4,120,536
Controlled sorting
Pass state.sorting and onSortingChange to control it yourself — for example to sort on the server (manualSorting: true).
tsx Copy
const [sorting, setSorting] = React.useState([])
const table = useDataTable({
data,
columns,
state: { sorting },
onSortingChange: setSorting,
manualSorting: true,
})