Skip to content

Global search

The search box in the toolbar matches what you type against every searchable column at once, with a fuzzy matcher that forgives word order, prefixes and missing letters. It is on by default.

Nia Silvania.silva@mail.testDesignInternActiveNigeria—
Meera Smithmeera.smith@team.devDesignAnalystInvitedAustralia—
Kavya Nairkavya.nair@example.comDesignAnalystInvitedCanada—
Freya Müllerfreya.muller@example.comPlatformDesignerActiveSingapore—
Mateo Khanmateo.khan@example.comGrowthDesignerPausedSingaporeAsked about invoices.
Liam Nairliam.nair@mail.testDesignInternActiveSingapore—
Liam Tanakaliam.tanaka@team.devGrowthDesignerInvitedJapanSpeaks at meetups.
Zara Sharmazara.sharma@corp.exampleDesignPMActiveBrazil—
Liam Reddyliam.reddy@mail.testPlatformDesignerActiveJapan—
Sofia Patelsofia.patel@example.comDesignLeadActiveJapan—
29 rows
Page 1 of 3

Type. The grid waits 200 ms after the last keystroke, then filters. The × in the box, or Esc while the box has focus, clears it.

<DataGrid data={data} columns={columns} /> // fuzzy, the default
<DataGrid data={data} columns={columns} globalFilter="includesString" /> // plain substring
<DataGrid data={data} columns={columns} globalFilter={false} /> // no search box

With the default "fuzzy" matcher, each cell’s text is scored against the query by rankMatch:

Tier The cell… Example for ann
6 equals the query Ann
5 starts with it Annette
4 has a word that starts with it (after a space, _, -, ., / or () Mary Ann
3 contains it Joanna
2 has initials that start with it (the first letter of each word) Aarav Nair Nguyen
1 contains its letters in order, with gaps Ananya
0 none of the above: no match

A row passes when any searchable cell scores above 0. The tiers decide what matches; they do not reorder the rows, so the sort you have chosen still decides the order. Matching is case-insensitive.

"includesString" is TanStack’s built-in: the cell contains the query, case-insensitively, and nothing looser. Choose it when a short query on a big grid matches too much by subsequence.

Every column with an accessor, except:

  • the utility columns (select, expander, rowNumber, actions);
  • a column with enableGlobalFilter: false;
  • display columns, which have no value to search.
col.text("notes", { enableGlobalFilter: false }) // free text that should not make a row match
  • Search sees the raw value, not the formatted cell: a date is matched as its ISO string, a currency as the bare number, an enum as its value rather than its label, an array as its items joined by spaces. Searching for “$1,200” finds nothing; “1200” does.
  • Search and column filters combine: a row must pass both.
  • A change takes the pager back to page 1. With grouping on, groups that end up empty disappear.
  • The value lives in grid.table.state.globalFilter; grid.table.setGlobalFilter("ann") sets it from your own control and the box follows. initialState={{ globalFilter: "ann" }} starts with a query, and the state adapter (globalFilter, onGlobalFilterChange) lets the URL own it.
  • With server-side data, the grid passes the query on through the state and leaves the rows alone.
  • The box is the DataGridSearch part. Put it anywhere inside DataGridRoot when you compose your own toolbar; toolbar={{ search: false }} removes it from the built-in one.
Key Where What it does
Esc in the search box Clear the query
Option Type Default What it does
globalFilter string or false "fuzzy" The matcher, "fuzzy" or "includesString", or no search at all.
enableGlobalFilter (column) boolean true false keeps the column out of the search.
initialState.globalFilter string "" The starting query.
state.globalFilter adapter With state.onGlobalFilterChange, another owner for the query.
search the toolbar true Show the box: toolbar={{ search: false }} hides it.
labels.search string "Search…" The placeholder and accessible name.