Limitations of the custom element
What the element cannot do, and why. Everything here is a consequence of the boundary between a compiled Svelte component and a host that is not Svelte - none of it is a to-do list.
Attributes cannot carry objects
An HTML attribute is a string. columns, data, groupBy, features,
treeData and 21 others are arrays, objects or functions, so they are settable
only as properties:
grid.columns = [...] // works
<sv-grid columns="[...]"></sv-grid> <!-- does not: it is the string "[...]" -->
The reference lists exactly which props have an attribute (72) and which are property-only (26).
No React, Vue or Angular components inside a cell
Column format and HTML-string renderers - what to use instead.
Open the live example: Custom cells + themes (Rows & Cells)
<SvGrid>'s renderDetailRow prop takes a Svelte snippet, which is a
compile-time construct. A host page has no way to author one, so the element
does not expose it.
For cell content, the substitutes are real and cover most cases:
- Column
formatoptions for numbers, dates and currency. fieldFnfor a derived display value.- An HTML-string renderer on the column, for badges, links and inline SVG.
cellClassfor styling, which is a plain function and crosses fine.
What you cannot do is mount a framework component per cell. If a grid's cells must render your own components, use the Svelte component directly.
Initial-only props stay initial
pageSize seeds state at mount; page changes go through the api, as here.
Open the live example: Cursor (keyset) pagination (Server-Side Data)
Some props seed state at mount rather than being live bindings - pageSize is
documented as "Initial page size", and initialSorting, initialColumnPinning
and initialAdvancedFilter say so in their names.
<!-- works: read at mount -->
<sv-grid pageable page-size="25"></sv-grid>
grid.pageSize = 25 // after mount: no effect, by design
grid.api.setPageSize(25) // use the api instead
This is grid behaviour, not an element limitation, but it surprises people more here because a custom element invites setting properties after upgrade.
Bundle size
The element bundles the grid and the Svelte runtime into one file, about
104 KiB gzipped for the entry plus lazy chunks on demand. That is the price of
a self-contained drop-in: a Svelte app importing @svgrid/grid shares the
runtime it already has and ships less.
If you are already on Svelte 5, use the component, not the element.
Type checking is on you
The element is plain JavaScript at the boundary - assigning grid.columns is
an untyped property write. TypeScript shows how to declare
the element so TSX and TS get completion back, but nothing checks a runtime
property assignment for you the way <SvGrid> does in a Svelte file.
Two elements, not one switch
<sv-grid> and <sv-grid-shadow> are separate elements because Svelte resolves
customElement.shadow when the component is compiled. No attribute can switch a
single element between light and shadow DOM. See shadow DOM.
See also
- Quick start
<sv-grid>reference- Enterprise features - what the paid pack adds here, and which half of it needs a Svelte-aware bundler.
- Missing features - the grid's own honest gap list.
Live examples
- Custom cells + themes - Avatars, sparklines, progress bars, density toggle, dark mode, full a11y.
- Cursor (keyset) pagination - Modern alternative to offset paging: prev / next cursor tokens, stable under writes, O(log N) deep pages.
Related articles
- Web Components - Write Once, Use in React, Vue, and Angular - How to wrap SvGrid as a custom element, wire it across React, Vue, and Angular, and avoid the three interop traps that bite every team the first time.
- Progress and Percentage Bar Cells in SvGrid - Build in-cell progress bars in your Svelte 5 data grid - with color thresholds, accessible markup, and sorting that still works.
- A Custom Column Header Menu in SvGrid - Build a per-column header menu for sort, hide, pin, and custom actions using header snippets and your own dropdown component.