Svelte Server-Side Table
When the dataset is too large to send, the grid stops owning the rows and starts asking for them. You implement one getRows function that receives the current sort, filters and row range and returns the rows plus a total count; the grid handles caching, request cancellation, race safety and the loading state.
The same contract covers offset paging, keyset or cursor paging, infinite scroll and server-side grouping, so moving from one to another is a change of options rather than a rewrite.
Install
npm i @svgrid/gridFree and MIT-licensed in @svgrid/grid: no license key, no row cap, no watermark.
The code
import { createServerDataSource, type ServerDataSource } from '@svgrid/grid'
const source: ServerDataSource<Row> = {
async getRows({ startRow, endRow, sortModel, filterModel }) {
const res = await fetch('/api/rows', {
method: 'POST',
body: JSON.stringify({ startRow, endRow, sortModel, filterModel }),
})
const { rows, total } = await res.json()
return { rows, rowCount: total } // rowCount = total AFTER filtering
},
}
const ctl = createServerDataSource(source, { pageSize: 50, onChange: (s) => (view = s) })
ctl.refresh()What you get
- One getRows contract - A single function receives the row range, the sort model and the filter model, and returns rows plus the filtered total. Everything else is handled.
- Debounce and cancellation - Typing in a filter does not fire a request per keystroke, and a superseded request is cancelled rather than racing the one after it.
- Keyset paging - Cursor-based paging for tables where OFFSET gets slow, with the same grid props as offset paging.
- Infinite scroll - Fetch the next block as the user scrolls, keeping a sliding window of rows in memory instead of the whole result.
- Server-side grouping - Group nodes expand one level at a time through the same contract, so the grid holds only the groups you opened.
- Free and MIT - The server row model, cursor paging and server grouping are all in @svgrid/grid.
Live examples
- Server-Side Row Model (SSRM) - One datasource contract for server-backed data: implement a single async getRows({ startRow, endRow, sortModel, filterModel }) and createServerDataSource owns the sort/filter/page lifecycle and races stale responses away. Here a 100,000-row in-memory server behind 250ms latency; the grid holds only the current 50-row page.
- Server-side data - Sort/filter/page round-tripped to a mock endpoint with debounce + cancel.
- Server-side infinite scroll - 100k-event audit log behind a mock API. Sparse chunked load on scroll; sort + filter + search pushed to the server.
- Cursor (keyset) pagination - Modern alternative to offset paging: prev / next cursor tokens, stable under writes, O(log N) deep pages.
- Server grouping (first-class) - First-class server-side grouping through one getRows contract: the request carries groupBy + groupKeys, and createServerGroupModel owns the group tree - lazy expand per level, aggregation, per-node caching, race-safety - handing back a flat displayRows list. Here a 63,000-row in-memory server behind 200ms latency; the grid holds only the groups you expand.
- Loading from REST - Fetches rows from a public REST API with loading skeleton, retry, error surface, and a Reload button.
Documentation
- Server-side data - The patterns for moving sort, filter, group, and pagination off the client and onto your API. Three flavours, ranked by complexity:
- Server-Side Row Model (SSRM) - When the data lives on the server - millions of rows in a database - the grid should hold only the page on screen and push sorting, filtering, and paging to…
- Server-side data (load on demand) - When the rows live behind an API and there are too many to ship to the browser, the server does the work: sorting, filtering, and paging become query…
Related articles
- 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.
- Client-Side vs Server-Side Data for Tables - The architectural fork that determines your grid's performance ceiling - how to pick the right data mode and wire it correctly in SvGrid.
- Inside SvGrid: Server-Side Data and the Headless Core - How SvGrid separates UI state from row processing, and what that means for building grids driven entirely by a backend.
Frequently asked questions
How do I do server-side pagination in a Svelte table?
Create a ServerDataSource with a getRows function that receives startRow, endRow, sortModel and filterModel, and return the rows with the total count after filtering. Pass the controller's state to the grid.
What does the grid send to my endpoint?
The requested row range plus the current sort model and filter model. You decide how to turn those into SQL or an API call; the grid never assumes a backend.
Does it support infinite scroll?
Yes. Turn pagination off and the grid requests the next block as the user scrolls, keeping a window of rows rather than the entire result set.
Is server-side data free?
Yes. The server row model, infinite scroll, cursor paging and server-side grouping are MIT-licensed in @svgrid/grid.