Knit UI
GitHub

Playground

Loading playground…

Playground
<SvgImage
  id="pin"
  svg={pin("#ef4444")}
  width={40}
  height={40}
/>

Examples

Fixed Size Icons

The SVG pin is drawn as a 40px icon at three cities. Zoom in/out — the pins keep their pixel size instead of scaling with the map.

Loading example…

Fixed Size IconsSourceStorybook

From Url

The icon is loaded from a URL rather than inline markup. An .svg (or data:image/svg+xml) URL is fetched and rasterized; here we use a data: URL so the story runs offline, but any CORS-enabled https://…/pin.svg works the same way.

Loading example…

From UrlSourceStorybook

Data Driven Icons

Several distinct icons registered at once via SvgImages, with each marker choosing its icon from its category property through a data-driven iconImage expression. Still a single GPU SymbolLayer.

Loading example…

Data Driven IconsSourceStorybook

Ten Thousand Markers

10,000 SVG-icon markers, unclustered — every point is its own symbol. iconAllowOverlap/iconIgnorePlacement keep them all visible (no collision thinning), which is the stress case for this many symbols.

Loading example…

Ten Thousand MarkersSourceStorybook

Ten Thousand Data Driven

10,000 markers across three icon types selected by category, unclustered. One rasterized bitmap per type, one GPU SymbolLayer drawing them all.

Loading example…

Ten Thousand Data DrivenSourceStorybook

Ten Thousand Clustered

The same 10,000 points, clustered. The source aggregates dense points into count bubbles (cluster); a CircleLayer + SymbolLayer render the clusters (sized/colored by point_count), and individual leaves fall back to the SVG pin. Zoom in to break clusters apart.

Loading example…

Ten Thousand ClusteredSourceStorybook

Fifty Thousand Clustered

50,000 markers, clustered — the recommended way to show this many points. supercluster aggregates dense points into count bubbles that split apart as you zoom in, keeping the visible symbol count low at every zoom and well under MapLibre's per-bucket symbol limit.

Loading example…

Fifty Thousand ClusteredSourceStorybook

Props

PropTypeDefaultDescription
id requiredstringImage id referenced by a `SymbolLayer` via `iconImage`.
heightnumber | undefinedTarget height in CSS pixels. Defaults to the SVG's intrinsic height.
pixelRationumber | undefinedMultiplier for the rasterized bitmap resolution (crispness). Default `1`.
sdfboolean | undefinedRender as a signed-distance-field icon (recolorable via `iconColor`).
sourceImageEntry | undefinedPre-rasterized image registered as-is (a `require()` asset or `{ uri }`). Skips rasterization; takes precedence over `svg`/`uri`.
svgstring | undefinedInline SVG markup. Rasterized to a bitmap on both web and native.
uristring | undefinedURL of a resource. An `.svg` (or `data:image/svg+xml`) URL is fetched and rasterized; any other URL (`.png`, `.jpg`, …) is registered directly as a raster. Ignored when `svg` or `source` is provided.
widthnumber | undefinedTarget width in CSS pixels. Defaults to the SVG's intrinsic width.