Render a seat map
The minimum SDK call — mount the Seats chart inside a div, listen for selections.
Render a seat map
The smallest useful Seats integration is two steps: drop a <div>
container into your page and call SeatsIO.render with your public
key, the event key, and the container id.
1. Add a container
Reserve a sized region of the page for the chart. The SDK fills the container — give it explicit width and height (or constrain it with flex / grid) so Konva can compute the canvas viewport.
<div id="seats-container" style="width: 800px; height: 600px;"></div>2. Call render
import SeatsIO from '@seats/sdk';
const chart = SeatsIO.render({
publicKey: 'pk_live_xxx',
eventKey: 'evt_xxx',
container: 'seats-container',
apiUrl: 'https://api.your-host.example',
maxSelectedObjects: 4,
onObjectSelected: ({ objectLabel, holdToken }) => {
console.log('Selected', objectLabel, 'with hold', holdToken);
},
});Every option except publicKey, eventKey, and container has a
sensible default. apiUrl defaults to the same origin as the page in a
typical SSR / proxy setup, but most self-hosted deployments set it
explicitly to the API host.
What you get
The rendered chart is interactive out of the box:
- Free seats highlight on hover.
- Click on a free seat fires
onObjectSelectedwith the seat label and a short-livedholdToken. Stash the token — you'll need it to promote the hold to a booking server-side. - Held / booked seats are not selectable and visually dim.
maxSelectedObjectscaps the buyer's selection; the SDK rejects clicks beyond the cap and surfaces a toast.
The full e-commerce variant — adding-to-cart, confirming at checkout, recovering from expired holds — is documented in Hold seats and confirm at checkout.
Callbacks reference
onObjectSelected fires once per seat. To track the whole selection,
listen for onSelectionValid — it fires on every change and hands you the
complete array of currently-held labels.
| Callback | Payload | Fires when |
|---|---|---|
onObjectSelected | { objectLabel, holdToken, categoryKey } | A single seat is selected and successfully held. Fires once per seat. |
onObjectDeselected | { objectLabel } | A single seat is deselected (its hold is released best-effort). |
onSelectionValid | { selectedObjectLabels } | The selection changes and at least one seat is held. selectedObjectLabels is the full current selection. |
onSelectionInvalid | { selectedObjectLabels, reason } | The selection becomes empty or a hold fails. reason is 'max_selected', 'hold_expired', or 'hold_failed'. |
onChartRendered | { chartData } | The initial chart render completes (fires once). |
const chart = SeatsIO.render({
publicKey: 'pk_live_xxx',
eventKey: 'evt_xxx',
container: 'seats-container',
apiUrl: 'https://api.your-host.example',
maxSelectedObjects: 4,
onSelectionValid: ({ selectedObjectLabels }) => {
// The complete current selection, e.g. ['A-12', 'A-13'].
console.log('Selected so far:', selectedObjectLabels);
},
onSelectionInvalid: ({ reason }) => {
if (reason === 'hold_expired') promptReselect();
},
});Configuration reference
| Option | Type | Required | Default | Notes |
|---|---|---|---|---|
publicKey | string | yes | — | A pk_* publishable key — safe to expose in the browser. |
eventKey | string | yes | — | The event to render seat availability for. |
container | HTMLElement | string | yes | — | A DOM element or its id. Must have an explicit height. |
apiUrl | string | yes | — | Base URL of your SeatBuilder API. Required since @seats/sdk 1.0.0. |
maxSelectedObjects | number | no | unlimited | Caps the buyer's selection; clicks beyond the cap surface a toast and fire onSelectionInvalid with reason: 'max_selected'. |
showSeatLabels | boolean | no | false | Show per-seat number labels (still hidden below the ~0.43× zoom threshold). |
Instance API
SeatsIO.render() returns a ChartInstance for imperative control:
| Member | Signature | Purpose |
|---|---|---|
holdToken | string | The session hold token. Share it with your backend to book the held seats. |
clearSelection | () => void | Deselect all seats and release their holds. |
selectObjects | (labels: string[]) => Promise<void> | Programmatically select (and hold) seats by label. |
destroy | () => void | Tear down the chart and release all resources. |
Integration walkthrough
End-to-end integration — create a chart, publish it, run an event, render the SDK, hold a seat, book it, and verify the webhook delivery.
Hold and book seats at checkout
The deferred-countdown e-commerce flow — instant cross-user lock on select, a short browse TTL, extend to a payment window at checkout, an integrator-owned countdown, and graceful handling of expired or contested holds.