Multi-scene experiences
Real 3D apps rarely show one fixed scene. A game moves the player between levels; a configurator or product viewer swaps models in and out; an architectural walkthrough crosses rooms or floors. Uptimizr treats all of these as scenes within one session — you keep a single tracker running and tell it when the active scene changes.
Why one session, not many
Section titled “Why one session, not many”Stopping and restarting tracking on every level/model change would fragment the visit into
disconnected sessions and break replay continuity (the timeline must stay ordered and
sessionId-keyed). Instead, keep one trackScene(...) client alive for the whole visit and mark
the transitions. Each scene becomes a segment of the same session, so you can:
- compare heatmaps, dwell, and performance per level / per model, and
- still replay the entire visit end to end as one ordered stream.
The two calls
Section titled “The two calls”Set the initial scene id when you start, then call setScene(id) every time the active scene
changes.
const client = trackScene(scene, { projectId, endpoint, meta: { sceneId: "level-1" }, // initial scene / area / model});
// Later, when the next scene loads:client.setScene("level-2");setScene emits an ordered scene_change marker and stamps the new sceneId onto every
subsequent event, so gaze/click heatmaps, mesh interactions, performance, and custom events are
all attributable to the scene that was active when they happened. Filter any read endpoint by the
scene query param to get per-scene results.
Patterns
Section titled “Patterns”Call setScene from your level-loaded hook, after the new level is live:
async function loadLevel(id: string) { await engine.loadLevel(id); client.setScene(id); // e.g. "level-3", "boss-arena"}Use stable, low-cardinality ids (the level’s slug), not a per-playthrough guid — that keeps aggregates meaningful across visitors.
When the visitor switches the displayed model, treat each model as a scene:
function showModel(sku: string) { viewer.load(sku); client.setScene(sku); // e.g. "sku-chair-walnut"}Now each model has its own view-direction and click heatmaps even though they share one canvas and one session.
For a continuous walkthrough, fire setScene on the trigger that marks entering a new area
(portal volume, teleport, floor change):
onRoomEnter((room) => client.setScene(room.id)); // "lobby", "gallery-2", "roof"Querying per scene
Section titled “Querying per scene”Most read endpoints accept a scene filter, so you can scope an aggregate to a single
level/model/area. Reads are scoped to the project behind your x-api-key — there is no
projectId query param:
curl "$ENDPOINT/api/v1/meshes/dwell?scene=level-2" \ -H "x-api-key: $KEY"Omit the filter to see the whole session across all scenes, and use /api/v1/scenes to list the
distinct scenes that have activity. See the query endpoints for the full
parameter list.
Replay across scenes
Section titled “Replay across scenes”Because the transitions are recorded as ordered scene_change markers in the same stream, session
replay re-drives the visit through every scene change in order — your replay
target can switch levels/models in lockstep by reacting to the scene_change events.
Related
Section titled “Related”- Custom events & input — the rest of the client API (
track,trackInput). - Sessions & lifecycle — how a session starts, flushes, and ends.
- Query endpoints — filtering aggregates by
sceneId.