Booking Client (Renderer) API Changes - v1.72.0
Release: v1.72.0
Package: @seatmap.pro/renderer
Date: 2026-08-28
Summary
Backward Compatible: MOSTLY — see Behaviour changes below
New Features: 5
Deprecations: 3
Bug Fixes: 5
Migration Required: NO for an integration that upgrades the renderer and the booking-service together and does not call setGaCategory with a numeric 0. Everything else is additive or keeps a deprecated alias working.
New Features
Orphan seat prevention (SEAT-1196, SEAT-1200, SEAT-1203)
A seat map can be configured to refuse a selection that would leave a single seat with no available neighbour. It is off unless enabled for the organisation.
Settings
orphanPrevention?: boolean;
Overrides what the buyer is shown. Omit it to follow the value the event price payload carries. The booking endpoints always apply the value configured for the organisation regardless of this setting.
Callback
onOrphanSeatsBlocked?: (event: IOrphanSeatsBlockedEvent) => boolean | Promise<boolean>;
interface IOrphanSeatsBlockedEvent {
attempted: number[];
orphaned: number[];
remedy: { select: number[]; deselect: number[] } | null;
}
Return true to accept the suggested adjustment, false to turn the selection down and explain it in your own interface. remedy is null when no combination would make the change acceptable, or when a seat it needs cannot be selected.
Without the callback, a blocked selection on a path that is not adjusted automatically is simply refused.
Programmatic cart methods
initCart, addSeatsToCart, removeSeatsFromCartByIds and removeSeatsFromCartByKeys now return:
interface ICartChangeResult {
applied: boolean;
orphaned: number[];
remedy: { select: number[]; deselect: number[] } | null;
}
applied and orphaned answer different questions and must both be read. applied says whether the cart changed; orphaned says whether the change strands a seat.
| Method | When it would strand a seat |
|---|---|
addSeatsToCart |
Adds nothing. applied: false, orphaned non-empty |
initCart |
Applies the restore and reports. applied: true, orphaned non-empty |
removeSeatsFromCartByIds |
Applies the release and reports. applied: true, orphaned non-empty |
removeSeatsFromCartByKeys |
Applies the release and reports. applied: true, orphaned non-empty |
These methods are synchronous and never adjust a selection themselves. With orphan prevention off they report nothing, and an integration that ignores the return value is unaffected.
Theme
theme.orphanGroup?: IOrphanGroupStyle;
Restyles the dashed outline that groups seats which can only be taken together.
Clear categories without resetting the palette (SEAT-1091)
clearSeatsCategory(seats): void;
clearGaCategory(sections): void;
resetSeatsCategories(): void;
resetGaCategories(): void;
resetCategories() is unchanged and remains the only call that also clears the shared category colour palette. Clearing a seat category removes just the category and leaves the rest of the seat’s data in place.
Categories by list and by name (SEAT-1092)
setGaCategory now takes a list of sections — objects, IDs, or section names — plus an optional colour, matching setSeatsCategory. Both setters accept a string category key as well as a number, so a category can be addressed as 'vip'. A named category needs a colour: only numeric categories fall back to the theme palette.
Mixed marquee selection (SEAT-1094)
renderer.setMode('selectMixed');
One drag selects seats and general admission sections together, reporting seats through onSeatsSelectionChange and onSeatsSelect and sections through onSectionsSelectionChange. Seated sections are left out of the section results. select, selectRows and selectSections are unchanged. Admin renderer only.
Eagle-view threshold and outline visibility (SEAT-1201)
eagleViewMaxZoom?: number; // default 0.5; 0.66 in the admin renderer
outlineVisibility?: {
svg?: 'always' | 'eagle-only' | 'hidden';
shape?: 'always' | 'eagle-only' | 'hidden';
auto?: 'always' | 'eagle-only' | 'hidden';
fallback?: 'always' | 'eagle-only' | 'hidden';
};
outlineVisibility now takes effect as documented, per outline source. eagleViewMaxZoom sets the scale below which the whole venue is in frame and outlines carry the navigation.
Behaviour changes
These are the only changes an existing integration may need to act on.
| Call or setting | Before | Now |
|---|---|---|
setGaCategory(sections, 0) |
Cleared the category | Assigns category 0. Pass undefined to clear |
setSeatsCategory without a colour |
Discarded the registered colour | Keeps the colour already registered for that category |
| Price payload with no orphan-prevention value | Treated as off | Treated as on. Set orphanPrevention: false to opt out |
| A click the orphan rule turns down | Refused | Completed with the suggested adjustment, unless onOrphanSeatsBlocked refuses |
| Section states on rectangular GA sectors | Not rendered | Rendered |
A removal that would strand a seat is still turned down rather than adjusted, and so is a click under a group size above one. onOrphanSeatsBlocked overrides the automatic adjustment on any of these paths.
Deprecations
All three keep working; the replacement is preferred.
| Deprecated | Replacement |
|---|---|
seatSelectionMinZoom |
eagleViewMaxZoom — honoured when it is absent |
disableOutlinesInHelicopterView |
outlineVisibility: { svg: 'eagle-only' } |
setSeatsCategory(seats, -1) |
clearSeatsCategory(seats) |
Bug Fixes
General admission selection is cleared (SEAT-1089)
Clicking empty space clears a selected sector or section and reports the emptied selection through onSectionsSelectionChange. Clicking a second sector deselects the first. Multi-select in selectSections mode still accumulates. The cart is never touched by a selection change.
Section states on rectangular shapes (SEAT-1093)
setSectionSelection, disableSections and filterSections now show on general admission sectors and rectangular tables. Section geometry — hit areas, zoomToSection targets and centroid labels — is unchanged.
Seat colours repaint on lock and filter (SEAT-1122)
Locking, unlocking, filtering and unfiltering seats repaint every layer. disableSectionsByIds and enableSectionsByIds do the same and refresh the section metadata getSections reports. These calls now fire onRedrawStart and onRedrawEnd.
Outline visibility honours the zoom ranges (SEAT-1201)
visibilitySettings.outlines.visible decides whether outlines are painted at the current scale; visibilitySettings.outlines.selectable decides whether they respond to the pointer. Outside the selectable range the click reaches the seats underneath. Integrators who want outlines at every zoom should set visibilitySettings.outlines.visible to { from: 0, to: 20 }.
The orphan group outline is drawn where it can be used (SEAT-1211)
The dashed outline appears once the map is zoomed in far enough to pick seats, rather than sharing a container the renderer puts away at that zoom. It is no longer drawn across the whole venue, where a two-seat group reads as a smudge.
Caching
The hosted renderer script is now served with Cache-Control: no-cache, so a browser revalidates it on each load and a release reaches an embedding page as soon as it is reloaded (SEAT-1214). Revalidation returns an unchanged response when the build has not moved. Integrators running their own cache in front of our host should confirm it forwards the revalidation.
Installation
npm install @seatmap.pro/renderer@1.72.0
The buyer-facing guidance for orphan seat prevention needs renderer 1.72.0 or newer. Upgrade an embedded build before the option is enabled for your organisation.