Sort, filter, paginate
Three most-asked-for features wired together against ~5k rows.
A live, editable Svelte 5 data grid example from the SvGrid gallery (Filtering & Search). See the SvGrid documentation for the full API.
About this example
Sorting, filtering and pagination wired together in the Svelte 5 data grid over 5,000 rows. Shift+click headers for multi-column sort, a per-column filter row for text and numbers, and a pagination footer with a page-size selector, from rowSortingFeature, columnFilteringFeature and rowPaginationFeature. The component owns the state so it can be persisted, here in the URL.
Three most-asked-for features wired together against a 5,000-row dataset.
- multi-column sort (shift-click headers)
- per-column filter row (text/number)
- pagination footer with page-size selector State is owned by this component so it can be persisted (here: in URL).
Imports, features and API used
Imports: @svgrid/grid, ../shared/seed
Table features registered: rowSortingFeature, columnFilteringFeature, rowPaginationFeature
Columns: firstName (First name), lastName (Last name), department (Department), country (Country), age (Age), salary (Salary), joinedAt (Joined)
Frequently asked questions
How do I enable pagination?
Register rowPaginationFeature in features and set showPagination with a pageSize. The footer renders page controls and a page-size selector; the current page is grid state.
How do I sort by more than one column?
Click a header to sort by it and Shift+click another to add it as a secondary key. The sort indicators show the order; clicking again cycles direction and off.
How is the state kept in the URL?
The component holds sorting, filters and page in its own state, serializes them into the query string when they change and reads them back on load, so a link reproduces the same view.
Related documentation
Related articles
- Excel-Style Filtering for Your Svelte Data Grid - Per-column filter menus, a filter row, global search, and server-side filtering - all wired through a single columnFilteringFeature in SvGrid.
- Server-Side Data - Pagination, Sorting, and Filtering on the Backend - Keep 100,000+ rows on the server. SvGrid owns the UI state for sort, filter, and pagination controls - your API owns the data.
- How We Built Excel-Style Filters - How SvGrid implements per-column filter menus, type-aware operators, and a shared filter model that works identically for in-memory and server-side data.
Source code (02-sort-filter-paginate.svelte)
<!-- Documented in: docs/help/recipes.md -->
<script lang="ts">
/**
* 02. Sort · Filter · Paginate
* ----------------------------
* Three most-asked-for features wired together against a 5,000-row dataset.
* - multi-column sort (shift-click headers)
* - per-column filter row (text/number)
* - pagination footer with page-size selector
* State is owned by this component so it can be persisted (here: in URL).
*/
import {
SvGrid,
tableFeatures,
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
type GridColumns,
} from '@svgrid/grid'
import { makePeople, type Person } from '../shared/seed'
const features = tableFeatures({
rowSortingFeature,
columnFilteringFeature,
rowPaginationFeature,
})
const rows = makePeople(5_000)
const columns: GridColumns<Person> = [
{ field: 'firstName', header: 'First name', editorType: 'text' },
{ field: 'lastName', header: 'Last name', editorType: 'text' },
{ field: 'department', header: 'Department', editorType: 'text' },
{ field: 'country', header: 'Country', editorType: 'text' },
{ field: 'age', header: 'Age', editorType: 'number' },
{
field: 'salary',
header: 'Salary',
editorType: 'number',
format: { type: 'currency', currency: 'USD', options: { maximumFractionDigits: 0 } },
},
{
field: 'joinedAt',
header: 'Joined',
editorType: 'date',
format: { type: 'date', pattern: 'y-m-d' },
},
]
</script>
<section class="flex flex-col flex-1 min-h-0 gap-3">
<div class="flex flex-wrap items-center gap-3 text-sm shrink-0">
<span class="sfp-strong">{rows.length.toLocaleString()} rows</span>
<span class="sfp-muted">·</span>
<span class="sfp-muted">
Click a header to sort. Shift+click to multi-sort. Type in the filter row.
</span>
</div>
<div class="flex-1 min-h-0">
<SvGrid responsive={true}
columnResize
data={rows}
columns={columns}
features={features}
filterMode="row"
selectionMode="none"
showPagination={true}
pageSize={50}
showGroupingControls={false}
enableInlineEditing={false}
enableCellSelection={false}
rowHeight={36}
containerHeight="100%"
fitColumns={true}
/>
</div>
</section>
<style>
.sfp-strong { color: var(--sg-fg, #475569); }
.sfp-muted { color: var(--sg-muted, #64748b); }
</style>More Filtering & Search examples
- Excel-style filters - Per-column operator dropdown with active-filter chips and clear.
- Filter - between operator - Number + date columns expose a "Between" operator with From/To inputs. Drive it via the menu or imperatively with api.setFilter(id, { operator: "between", value, valueTo }).
- Highlighted search matches - External search input + a custom cell snippet that wraps matched substrings in <mark>. Filters the dataset AND visually flags hits.
- Find in grid (Ctrl+F) - Built-in find overlay with next / previous navigation. Scans every visible cell value; matches activate + scroll into view.
- Locale-aware text filter - Pass filterLocale and the grid normalises text (NFD + diacritic strip + locale-aware lowercase) so "cafe" matches "Café", "tokyo" matches "Tōkyō".