Remote Data Grid
The remote variant fetches data asynchronously via a query function instead of receiving pre-loaded data. Import from @repo/table/remote.
Basic Usage
<script lang="ts">
import { DataGrid, useDataGrid } from '@repo/table/remote';
import { getUsers } from './users.remote';
const { table, dataGrid } = await useDataGrid({
tableOptions: {
columns: [
{ id: 'name', header: 'Name', accessorKey: 'name' },
{ id: 'email', header: 'Email', accessorKey: 'email' },
],
},
query: getUsers,
getRowLink: (row) => `/users/${row.original.id}`,
});
</script>
<DataGrid.Root {dataGrid} {table} title="Users" add="/users/add" />
useDataGrid is async -- use top-level await in Svelte 5 async pages/components.
RemoteDataGridOptions
| Option | Type | Description |
|---|---|---|
tableOptions | Partial<TableOptions<T>> | TanStack Table config |
query | RemoteQueryFunction<OverviewQueryParams<F>, PaginatedResult<T>> | Async function that fetches data |
getRowLink | (row: Row<T>) => string? | Row link generator |
filterSchema | z.ZodObject? | Zod schema for filters |
Query Function
The query function receives OverviewQueryParams:
interface OverviewQueryParams<F> {
filters?: z.infer<F>;
sorting: SortingState;
pagination: PaginationState;
}
Must return PaginatedResult<T> ({ data: T[], count: number }).
DataGrid Return Value
The remote dataGrid object exposes reactive getters and setters:
| Property | Type | Description |
|---|---|---|
paginationResultCount | number | Total result count |
getRowLink | GetRowLink<T> | Row link function |
filters | z.infer<F> | Current filter state |
setFilters | (value?) => void | Update filters and reload |
sorting | SortingState | Current sort state |
setSorting | (state) => void | Update sorting and reload |
pagination | PaginationState | Current pagination state |
setPagination | (state) => void | Update pagination and reload |
loading | boolean | Whether data is being fetched |
refresh | () => void | Re-fetch with current params |
Remote Filters
Use DataGrid.FilterForm inside DataGrid.Root children:
<script lang="ts">
import { DataGrid, useDataGrid } from '@repo/table/remote';
import { z } from 'zod/v4';
const filterSchema = z.object({
name: z.string().optional(),
status: z.enum(['active', 'inactive']).optional(),
});
const { table, dataGrid } = await useDataGrid({
tableOptions: { columns: [...] },
query: getUsers,
filterSchema,
});
</script>
<DataGrid.Root {dataGrid} {table} title="Users">
<DataGrid.FilterForm schema={filterSchema} />
</DataGrid.Root>
FilterForm reads dataGrid from Svelte context set by DataGrid.Root. It renders Apply/Clear buttons automatically.
createOverviewQuerySchema
Server-side helper to validate query params in your remote function:
import { createOverviewQuerySchema } from '@repo/table/remote';
import { z } from 'zod/v4';
const filterSchema = z.object({
name: z.string(),
status: z.enum(['active', 'inactive']),
});
const querySchema = createOverviewQuerySchema(filterSchema);
// Produces: z.object({
// pagination: z.object({ pageIndex: z.number().min(0), pageSize: z.number().min(1) }),
// sorting: z.array(z.object({ id: z.string(), desc: z.boolean() })),
// filters: filterSchema.partial().optional(),
// })
URL State
The remote data grid uses qs for URL serialization. Params:
?sort=name:ASC?page=2&pageSize=10?filter[name]=Alice&filter[status]=active
State updates call goto() to update the URL without navigation.
Type Helper
Extract the data type from a query function:
import type { QueryDataPoint } from '@repo/table/remote';
type User = QueryDataPoint<typeof getUsers>;