Venue document
Stable seat, row, section, floor, category, label, accessibility, and geometry identifiers.
Rendering selectable seats is a frontend task. Selling them is a distributed state problem: authoritative inventory, atomic holds, expiry, real-time updates, trusted pricing, idempotent booking, and recovery.
Scope: the working example below is intentionally browser-local. It teaches interaction—not double-booking prevention.
Each available seat is a button with a stable ID and an aria-pressed state. A JavaScript Set tracks the current browser selection. Sold seats are disabled.
JavaScript has not started. The guide remains readable.
This pattern is appropriate for learning, a static plan, or a narrow internal tool. It deliberately never labels local selection as a reservation.
// HTML: <button data-seat="A-1" aria-pressed="false">A1</button>
const selected = new Set();
document.querySelectorAll('[data-seat]').forEach((seat) => {
seat.addEventListener('click', () => {
const id = seat.dataset.seat;
const active = !selected.has(id);
active ? selected.add(id) : selected.delete(id);
seat.setAttribute('aria-pressed', String(active));
renderSummary([...selected]);
});
});
function renderSummary(ids) {
summary.textContent = ids.length
? `Selected locally: ${ids.join(', ')}`
: 'No seats selected.';
}
A renderer solves pixels, hit testing, and navigation. It does not decide who owns a seat when buyers compete.
| Layer | Useful when | Work you still own |
|---|---|---|
| DOM buttons | Small maps, direct semantics, simple layouts | Spatial navigation, dense-scene performance, venue geometry |
| SVG | Vector geometry, labels, inspectable seat nodes | Pan/zoom, large node counts, semantic focus model |
| Canvas | Dense 2D scenes and custom hit testing | Accessible equivalent, focus, text, selection semantics |
| WebGL | Very dense or spatially rich scenes | Rendering pipeline, picking, fallbacks, accessibility, device variance |
Primary implementation references reviewed 10 Aug 2026: Konva's React canvas reservation example, an open React/Konva seating editor, and the package documentation surfaced for react-seat-charts, seat-picker, and @seatsio/seatsio-react. Package status and APIs can change; confirm them at evaluation time.
The browser can request a change. Only the authoritative backend can decide whether that transition succeeds.
Stable seat, row, section, floor, category, label, accessibility, and geometry identifiers.
Free, held, booked, blocked, and released state owned outside the browser.
One decision point for competing requests; failure returns a conflict, not a second success.
Temporary ownership ends predictably and returns inventory without relying on an open tab.
Each buyer begins with a snapshot and applies later inventory deltas.
Your server reads fresh held items and applies pricing, payment, customer, and order rules.
A stable booking reference makes retry safe when a response is lost or delayed.
Signed webhooks, history, and reports recover outcomes beyond the request lifecycle.
Staff controls, blocked seats, accessibility filters, responsive behavior, and scoped authorization.
A client may optimistically highlight a seat, but the durable transition belongs to one event state owner.
The diagram explains the contract, not a universal throughput claim. SeatLayer's released evidence includes one scoped 30-way race for one contested seat: one hold succeeded and the other requests received conflicts.
DIY is a valid choice when the scope is deliberately narrow. An SDK is useful when the seating layer itself is becoming a product programme.
SeatPicker renders the complete buyer surface and hands your server an opaque holdId. Your server inspects fresh held items, applies pricing and payment, and confirms inventory with a stable booking reference.
npm install @seatlayer/js
import { SeatPicker } from '@seatlayer/js';
const picker = new SeatPicker({
container: '#seat-picker',
event: 'ev_9f3a',
onCheckout: async (_, __, handoff) => {
await fetch('/api/checkout', {
method: 'POST',
body: JSON.stringify({ holdId: handoff.holdId }),
});
},
});
picker.render();
Use the complete picker or the headless chart. Server SDKs and REST/OpenAPI cover the trusted side.
Review the complete developer platform →Open the quickstart docs ↗Inspect the web SDK on GitHub ↗View @seatlayer/js on npm ↗Create test credentials and run one event through render, hold, trusted inspection, booking, and signed webhook verification. Prefer to inspect first? Open the released buyer demo.