Embedding <Visualizer />
Common use cases: embedding a snapshot viewer next to a robot’s data, rendering test fixtures in a custom dashboard, or shipping the visualizer in a larger debugging surface.
Getting started
Section titled “Getting started”Prerequisites
Section titled “Prerequisites”A Svelte 5 / SvelteKit (or Astro+Svelte, Vite+Svelte, etc.) project. The package is svelte-typed and built for runes; you cannot consume it from Svelte 4.
Install
Section titled “Install”The package declares a long list of peerDependencies (Svelte, Threlte, Three.js, the Viam SDK, prime-core, several Zag.js components, etc.). pnpm will print warnings for any that aren’t already in your project — install whatever it asks for.
Disable SSR for the page
Section titled “Disable SSR for the page”Threlte renders WebGL, which needs the browser. Disable SSR on any page that mounts <Visualizer />. In SvelteKit:
Mounting <Visualizer />
Section titled “Mounting <Visualizer />”<Visualizer /> is the entire visualizer rendered as a single Svelte component. It expects an explicitly-sized parent because it stretches to fill its container:
That’s enough to get an empty scene with the camera, grid, and overlay UI. From there, you can:
- Pass
partIDto bind it to a specific Viam machine part. - Pass
cameraPoseto set an initial camera position and look-at target. - Pass
drawConnectionConfig={{ backendIP, websocketPort }}to make it stream from a running draw server (only needed if you wantclient/apicalls to render in this embedded instance — most apps leave this unset). - Provide a
childrensnippet to render your own Threlte primitives or the<Snapshot />component inside the scene.
Rendering snapshots
Section titled “Rendering snapshots”A snapshot is a serialized scene — every transform, drawing, and camera setting captured into one protobuf payload. Snapshots render purely client-side; no draw server, no live machine, no network calls.
Use the <Snapshot /> component as a child of <Visualizer />:
Put the snapshot in your app’s public/ (or static/) directory and fetch it at runtime. This is the pattern the playground uses.
Fetch and decode at runtime:
JSON snapshots are bigger but easier to debug:
You can re-bind a different snapshot at any time — <Snapshot /> watches the prop and respawns the scene entities when the value changes.
The playground renders this snapshot by default. To experiment with it, download visualization_snapshot.json, edit a few values, and drag the modified file onto the playground — the scene re-renders with your changes. The drop zone accepts .json, .pb, and .pb.gz snapshot files, but they must be named with a visualization_snapshot prefix (see src/lib/components/FileDrop/file-names.ts) for the loader to recognize them.
Producing snapshots
Section titled “Producing snapshots”Snapshots are produced from Go using the draw package. The most common pattern: build up a *draw.Snapshot, then call MarshalBinary() (or MarshalJSON() for human-readable output) and ship the bytes wherever your frontend can fetch them.
A minimal producer:
See the draw API reference for the full set of Snapshot.Draw* methods.
Using only the standalone components
Section titled “Using only the standalone components”A few components are exported via the /lib subpath and work without a <Visualizer /> parent — useful if you just need a piece of the visualizer (e.g. an axes helper) inside your own Threlte canvas:
<Snapshot /> is also exported from /lib, but unlike <AxesHelper /> it requires the context that <Visualizer /> provides — use it as a child of <Visualizer />, not standalone.