This tutorial adds a 3D seat view to a ticketing website: buyers orbit the venue, fly to a seat, and open its 360° view — then select that seat through the same picker and hold that already drives your 2D checkout. There is no separate 3D model to commission and no second chart to keep in sync; the 3D scene is built from the chart you already publish.
Test mode is free with no time limit and no card, so you can complete every step below before a live account exists. For a walkthrough of what buyers see, see what buyers see in a 3D seat map.
1. Install the package
npm i @seatlayer/js@^0.64.0yarn add @seatlayer/js@^0.64.0pnpm add @seatlayer/js@^0.64.0bun add @seatlayer/js@^0.64.0For script-tag, browser ESM, React, Vue, and Angular routes, see the install options for all frameworks.
2. Enable 3D on the SeatPicker
3D is a progressive enhancement of the picker you already mount. Two options
turn it on: enable3D for the interactive venue, and seatView for the 360°
view-from-seat actions.
const picker = new SeatPicker({
container: "#picker",
event: "ev_9f3a",
enable3D: true,
seatView: true,
});
await picker.render();enable3D is true when WebGL2 is available, and seatView is true by
default. Set enable3D: false when an embed must remain strictly 2D, and
seatView: false to hide 360° view-from-seat actions in both 2D and 3D.
3. Drive the view from your own UI
Buyers get a built-in Map | 3D switch. Your application can drive the same state — useful for a “show my seat” button or an order-history screen.
picker.setBuyerView("venue3d");
console.log(picker.getBuyerView()); // "venue3d"
// Enter 3D and move directly to a known seat.
picker.setBuyerView("venue3d", {
flyToSeatId: "A-12",
});
picker.setBuyerView("map");Calling setBuyerView("venue3d", { flyToSeatId }) while already in 3D moves the
existing camera without rebuilding the scene.
4. Mirror the view into your own route
onBuyerViewChange reports map/3D entry, exit, and targeted-seat changes as
{ view, seatId? }. Mirror it into a host route so a copied URL reopens the
same venue at the same seat.
const picker = new SeatPicker({
container: "#picker",
event: "ev_9f3a",
enable3D: true,
seatView: true,
onBuyerViewChange: ({ view, seatId }) => {
syncHostRoute({ view, seatId });
},
});The public demo does this with ?tour=3d&seat=<seat-id>, so browser Back and
Forward restore the map, the 3D overview, and the targeted seat without
rebuilding application state.
5. Forward the 3D journey to analytics
onAnalytics receives the same 3D events the picker emits, with
{ surface: "buyer" } plus event-specific properties.
const picker = new SeatPicker({
container: "#picker",
event: "ev_9f3a",
onAnalytics: (event, properties) => {
analytics.capture(event, properties);
},
});Current events include 3d_opened, 3d_orbit_engaged, 3d_seat_picked,
3d_cinematic_played, 3d_cinematic_skipped, 3d_cinematic_cancelled,
3d_panorama_opened, and 3d_panorama_closed. A failing analytics sink does
not break the picker.
6. Know the fallback behaviour
3D never becomes a requirement for selection or checkout:
- it is shown only when the browser supports WebGL2;
- it is lazy-loaded only when the buyer enters 3D; and
- it is always paired with the standard 2D map.
max3DSeats defaults to 60,000 on desktop and 30,000 on small or low-core
devices, and host overrides are accepted. Keep the built-in toggle
discoverable rather than forcing every buyer into 3D, keep any controls outside
the picker synchronized with getBuyerView(), and test low-power devices and
browser WebGL restrictions.
Before you ship
- WebGL2 available and unavailable both tested.
- A seat with an authored image and one using the generated fallback.
- Live availability changing while 3D is open.
- Keyboard exit and return to the 2D selection.
- Mobile portrait and reduced container heights.
- Host theming with sufficient text and control contrast.
Questions
How do I add a 3D seat preview to my ticketing website?
Install @seatlayer/js, mount SeatPicker on an event, and set enable3D: true
with seatView: true. The picker renders the 2D map, the interactive 3D venue,
and the 360° view-from-seat from the same published chart, so the seat a buyer
picks while orbiting the venue is the seat that enters the hold and your
checkout handoff.
Does the 3D view need a separate chart?
No. The 3D scene is built from the chart you already publish, and venue landmarks authored in the Designer are shared with the 3D scene rather than maintained as a separate model. The 3D scene receives the same availability and selection changes as the 2D picker, so seat state stays consistent while the buyer changes view.
Where do the 360° images come from?
SeatLayer resolves the closest available source: a seat or row-level authored image, then a floor-level fallback, then a venue-wide fallback, then a geometry-generated preview. Buyer UI distinguishes an authored image from a generated preview. See the 3D buyer view reference for the progressive-panorama metadata and the private-media transport rules.
Can I do this in React?
Yes — the same options apply to the React wrapper. Start from the
React seating chart tutorial and add
enable3D and seatView to the SeatPicker component it builds.
For the complete purchase flow, continue to the checkout example.