MRT logoMaterial React Table

Global Filtering (Search) Feature Guide

Material React Table has a powerful built-in global filtering (search) feature that uses a fuzzy matching algorithm and ranks/sorts the results based on how closely rows match the search query. In this guide we'll cover how to use, customize, or disable the global filter and search features to fit your needs.

Relevant Props

1
boolean
true
MRT Global Filtering Docs
2
boolean
true
MRT Global Filtering Docs
3
boolean
true
MRT Global Filtering Docs
4
(column: Column<TData, unknown>) => boolean
5
MRT_FilterOption
6
Array<MRT_FilterOption | string> | null
7
boolean
TanStack Table Filters Docs
8
TextFieldProps | ({ table }) => TextFieldProps
Material UI TextField Props
9
OnChangeFn<GlobalFilterState>
TanStack Table Filters Docs
10
OnChangeFn<GlobalFilterState>
TanStack Table Filters Docs
11
OnChangeFn<boolean>
12
'left' | 'right'
13
({ internalFilterOptions, onSelectFilterMode, table }) => ReactNode[]

Relevant Column Options

1
boolean

Relevant State Options

1
any
TanStack Table Filtering Docs
2
MRT_FilterFn
3
boolean
false

Disable Global Filtering

You can either disable the global filter feature entirely, or disable it for specific columns.

Disable Global Filtering per Column

If you simply want to not include a column as one of the columns that the global filter scans through during filtering, you can set the enableGlobalFilter option to false for that column.

const columns = [
{
accessorKey: 'id',
header: 'Id',
enableGlobalFilter: false, // do not scan this column during global filtering
},
{
accessorKey: 'name',
header: 'Name',
},
];

Disable Global Filter Feature

You can disable the global filtering feature and hide the search icon by setting the enableGlobalFilter prop to false.

<MaterialTable
columns={columns}
data={data}
enableGlobalFilter={false} //disable search feature
/>

Client-Side Global Filtering

Client-side filtering (and global filtering) is enabled by default. This means that the search box will scan through all columns and try to find matches for the search term.

Global Filter Function

You can use any of the built-in filterFns or any of the custom filter functions that you have defined in the filterFns prop, just like you would with the column filters.

<MaterialReactTable
columns={columns}
data={data}
globalFilterFn="contains" //turn off fuzzy matching and use simple contains filter function
/>

or a custom filter function:

<MaterialReactTable
columns={columns}
data={data}
filterFns={{
myCustomFilterFn: (row, id, filterValue) =>
row.getValue(id).startsWith(filterValue),
}}
globalFilterFn="myCustomFilterFn" //set the global filter function to myCustomFilterFn
/>

The default global filter function is set to fuzzy, which is a filtering algorithm based on the popular match-sorter library from Kent C. Dodds, though you can change the global filter function by setting the globalFilterFn prop.

Ranked Results

If you keep the default fuzzy filterFn option as the global filter function, you get an extra ranked results feature enabled by default. This means that when a user searches with the searchbox, the results will be sorted by the closest match first instead of the order the data was defined in.

If you do not want ranked results to be enabled, but you still want fuzzy matching, you can set the enableGlobalFilterRankedResults prop to false.

<MaterialReactTable
columns={columns}
data={data}
enableGlobalFilterRankedResults={false} //preserve the order of the data when fuzzy match searching
/>

Global Filter Modes

Similar to the column filter modes, you can enable the user to be able to choose between multiple different filter modes for the global filter with the enableGlobalFilterModes prop. You can then customize which filter modes are available in the dropdown by setting the globalFilterModeOptions prop, or by rendering your own custom menu items with the renderGlobalFilterModeMenuItems prop.

<MaterialReactTable
columns={columns}
data={data}
enableGlobalFilterModes //enable the user to choose between multiple search filter modes
globalFilterModeOptions={['fuzzy', 'startsWith']} //only allow the user to choose between fuzzy and startsWith filter modes
/>

Show Search Field by Default

Also, if you want to show the search text box by default and not hide it behind the search icon, you can set the showGlobalFilter state to true in the initialState.

Customize Global Filter Position

You can customize the position of the global filter (search box) in the top toolbar by setting the positionGlobalFilter prop to left or right. It is shown on the right by default.

<MaterialReactTable
columns={columns}
data={data}
positionGlobalFilter="left" //show the global filter on the left side of the top toolbar
initialState={{
showGlobalFilter: true, //show the global filter by default
}}
/>

Customize the Search Text Field

You can customize the search text field by passing in props to the muiSearchTextFieldProps prop. This is useful if you want to customize the placeholder text, add styles, or any other text field props.

<MaterialReactTable
columns={columns}
data={data}
muiSearchTextFieldProps={{
placeholder: 'Search all users',
sx: { minWidth: '300px' },
variant: 'outlined',
}}
/>

1HughJayMungus42
2LeroyLeroyJenkins51
3CandiceDeniseNutella27
4MicahHenryJohnson32

Rows per page

1-4 of 4

Source Code

1import React, { useMemo } from 'react';
2import MaterialReactTable from 'material-react-table';
3import { data } from './makeData';
4
5const Example = () => {
6 const columns = useMemo(
7 //column definitions...
32 );
33
34 return (
35 <MaterialReactTable
36 columns={columns}
37 data={data}
38 enableGlobalFilterModes
39 initialState={{
40 showGlobalFilter: true,
41 }}
42 positionGlobalFilter="left"
43 muiSearchTextFieldProps={{
44 placeholder: `Search ${data.length} rows`,
45 sx: { minWidth: '300px' },
46 variant: 'outlined',
47 }}
48 />
49 );
50};
51
52export default Example;
53

Manual Server-Side Global Filtering

A very common use case when you have a lot of data is to filter the data on the server, instead of client-side. In this case you will want to set the manualFiltering prop to true and manage the globalFilter state yourself like so. (Can work in conjuntion with manual column filtering)

// You can manage and have control over the columnFilters state yourself
const [globalFilter, setGlobalFilter] = useState('');
const [data, setData] = useState([]); //data will get updated after re-fetching
useEffect(() => {
const fetchData = async () => {
// send api requests when columnFilters state changes
const filteredData = await fetch();
setData([...filteredData]);
};
}, [globalFilter]);
return (
<MaterialReactTable
columns={columns}
data={data} // this will already be filtered on the server
manualFiltering //turn off client-side filtering
onGlobalFilterChange={setGlobalFilter} //hoist internal global state to your state
state={{ globalFilter }} //pass in your own managed globalFilter state
/>
);

Specifying manualFiltering turns off all client-side filtering, and assumes that the data you pass to <MaterialReactTable /> is already filtered.

Here is the full Remote Data example showing off server-side filtering, pagination, and sorting.


Rows per page

0-0 of 0

Source Code

1import React, { FC, useEffect, useMemo, useState } from 'react';
2import MaterialReactTable, { MRT_ColumnDef } from 'material-react-table';
3import type {
4 ColumnFiltersState,
5 PaginationState,
6 SortingState,
7} from '@tanstack/react-table';
8
9type UserApiResponse = {
10 data: Array<User>;
11 meta: {
12 totalRowCount: number;
13 };
14};
15
16type User = {
17 firstName: string;
18 lastName: string;
19 address: string;
20 state: string;
21 phoneNumber: string;
22};
23
24const Example: FC = () => {
25 //data and fetching state
26 const [data, setData] = useState<User[]>([]);
27 const [isError, setIsError] = useState(false);
28 const [isLoading, setIsLoading] = useState(false);
29 const [isRefetching, setIsRefetching] = useState(false);
30 const [rowCount, setRowCount] = useState(0);
31
32 //table state
33 const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
34 const [globalFilter, setGlobalFilter] = useState('');
35 const [sorting, setSorting] = useState<SortingState>([]);
36 const [pagination, setPagination] = useState<PaginationState>({
37 pageIndex: 0,
38 pageSize: 10,
39 });
40
41 //if you want to avoid useEffect, look at the React Query example instead
42 useEffect(() => {
43 const fetchData = async () => {
44 if (!data.length) {
45 setIsLoading(true);
46 } else {
47 setIsRefetching(true);
48 }
49
50 const url = new URL(
51 '/api/data',
52 process.env.NODE_ENV === 'production'
53 ? 'https://www.material-react-table.com'
54 : 'http://localhost:3000',
55 );
56 url.searchParams.set(
57 'start',
58 `${pagination.pageIndex * pagination.pageSize}`,
59 );
60 url.searchParams.set('size', `${pagination.pageSize}`);
61 url.searchParams.set('filters', JSON.stringify(columnFilters ?? []));
62 url.searchParams.set('globalFilter', globalFilter ?? '');
63 url.searchParams.set('sorting', JSON.stringify(sorting ?? []));
64
65 try {
66 const response = await fetch(url.href);
67 const json = (await response.json()) as UserApiResponse;
68 setData(json.data);
69 setRowCount(json.meta.totalRowCount);
70 } catch (error) {
71 setIsError(true);
72 console.error(error);
73 return;
74 }
75 setIsError(false);
76 setIsLoading(false);
77 setIsRefetching(false);
78 };
79 fetchData();
80 // eslint-disable-next-line react-hooks/exhaustive-deps
81 }, [
82 columnFilters,
83 globalFilter,
84 pagination.pageIndex,
85 pagination.pageSize,
86 sorting,
87 ]);
88
89 const columns = useMemo<MRT_ColumnDef<User>[]>(
90 () => [
91 {
92 accessorKey: 'firstName',
93 header: 'First Name',
94 },
95 //column definitions...
113 ],
114 [],
115 );
116
117 return (
118 <MaterialReactTable
119 columns={columns}
120 data={data}
121 enableRowSelection
122 getRowId={(row) => row.phoneNumber}
123 initialState={{ showColumnFilters: true }}
124 manualFiltering
125 manualPagination
126 manualSorting
127 muiToolbarAlertBannerProps={
128 isError
129 ? {
130 color: 'error',
131 children: 'Error loading data',
132 }
133 : undefined
134 }
135 onColumnFiltersChange={setColumnFilters}
136 onGlobalFilterChange={setGlobalFilter}
137 onPaginationChange={setPagination}
138 onSortingChange={setSorting}
139 rowCount={rowCount}
140 state={{
141 columnFilters,
142 globalFilter,
143 isLoading,
144 pagination,
145 showAlertBanner: isError,
146 showProgressBars: isRefetching,
147 sorting,
148 }}
149 />
150 );
151};
152
153export default Example;
154

View Extra Storybook Examples