---
title: "Multi-floor venues"
description: "Author one chart and event across floors, keep labels unique, and synchronize custom 2D/3D floor controls."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.seatlayer.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Multi-floor venues

One chart can contain several floors—for example Stalls, Dress Circle, and Upper
Circle. They publish together and share one event inventory and checkout flow.

## Author floors

1. **Add and name each floor**

   Use the Designer floor rail. Give levels buyer-readable names and stable ids.
2. **Author independent geometry**

   Each floor has its own objects, focal point, optional base height, private
   trace reference, and optional buyer background.
3. **Keep inventory identity global**

   Seat and grouped-object labels must remain unique across the entire chart,
   not only within a floor.
4. **Review together**

   Test floor switching, far-zoom navigation, 3D venue view, realtime state,
   and one hold containing inventory from more than one level.
5. **Publish once**

   The chart snapshot and resulting event cover every floor.

> **Logical floors and physical height are separate**
>
> Floors isolate authoring and buyer navigation. Physical 3D elevation comes
> from authored floor base heights and section geometry; do not assume the floor
> list alone creates correct architectural stacking.

## Buyer behavior

`SeatPicker` provides floor controls for multi-floor charts and the 3D venue view
can present the levels together. Live status is reapplied whenever the buyer
switches floor or view.

With a custom `SeatingChart` UI, use:

```js title="browser/floor-switcher.js"
const chart = new seatlayer.SeatingChart({
  container: "#chart",
  event: "ev_9f3a",
  onDeckTap: (floorId) => {
    setActiveFloorTab(floorId);
  },
});

await chart.render();

for (const floor of chart.getFloors()) {
  addFloorTab({
    label: floor.name,
    onSelect: () => chart.setFloor(floor.id),
  });
}
```

- `getFloors()` returns `{ id, name }[]` after `render()`.
- `setFloor(floorId)` changes the 2D floor.
- `onDeckTap(floorId)` synchronizes host UI after a 3D deck interaction.
- Calling `setFloor()` on a single-floor chart warns and has no effect.

## Inventory and checkout

A buyer may select across floors if your product allows it. The hold, inspected
items, payment, and atomic booking remain one transaction.

Show floor/section context in the cart so identical-looking row or seat labels
are understandable—even though validation should still keep booking identities
unique.

## 3D authoring quality

- Set realistic `baseHeightM` or section elevations where physical stacking is
  intended.
- Give every floor/zone a focal point toward the relevant stage or field.
- Check stairs, overhangs, and sightline expectations in buyer preview.
- Treat 3D as orientation evidence, not an accessibility-route certification.
- Verify acceptable behavior when WebGL2 is unavailable; the 2D floor switcher
  remains essential.

## Verification checklist

- [ ] Labels are unique across all floors.
- [ ] Every floor has a meaningful name and focal point.
- [ ] Physical elevation is authored, not inferred from order alone.
- [ ] Custom tabs and 3D deck taps stay synchronized.
- [ ] Realtime state remains correct after floor changes.
- [ ] A cross-floor hold books atomically in test mode.
- [ ] Mobile and keyboard floor navigation pass.
- [ ] The 2D experience is complete without WebGL2.

Continue with the [3D buyer view](/buyer-sdk/3d-view),
[charts and objects](/designer/charts-and-objects), or
[publishing and versioning](/designer/publishing-and-versioning).

Source: https://docs.seatlayer.io/designer/multi-floor-venues/index.mdx
