The Seat Plan widget is the simplest way to deliver a fully interactive seat plan to your customers, allowing them to visualise the layout of a venue, where their seats would be and select the seats, which they'd like to purchase.
Note: you can add only one reservation per basket. In case you are trying to add more items to the existing basket, you will see a warning popup.
Benefits
Visualised Seat PlansAll seat plans have been meticulously constructed for the vast majority of theatre and attraction venues which Encore support - allowing customers to see before they buy!
Fully InteractivePan, zoom in, zoom out, choose your sections, choose your seats - all seat plans offer super intuitive controls for your customers to choose their seats as easily as possible
Optimized across DevicesThe Seat Plan widget has been optimized across all channels - desktop, mobile, tablet - with full responsiveness and device-specific actions, like "pinch to zoom"
Built-in AvailabilityAll seat plans come built-in with your assigned performance-level availability - no need to make extra calls for availability and manipulate this data for display
Embedding the widget
To embed the Seat Plan widget:
- Ensure you've got a valid channel Id. This should be provided to you as part of your account setup.
- Create a new HTML page and add the following markup:
<!doctype html>
<html lang="en">
<head>
<title>Seat Plan example</title>
<!-- CSS file is optional and needed only if you want to use default styling -->
<link rel="stylesheet" href="https://venue-service.tixuk.io/v4/css/main.css" />
</head>
<body>
<div
data-app="venue-app"
data-view-name="seat-plan"
data-channel-id="{your-channel-id}"
data-product-id="{product-id}"
data-product-type="{show|attraction}"
data-performance-type="{A|M|E}"
data-performance-date="{date of performance e.g. 2019-01-10}"
data-performance-time="{time of performance e.g. 19:30}"
data-quantity="{number of tickets e.g. 2}"
data-api-path="{url where the booking will be made e.g. http://your-website-url}"
></div>
<script type="text/javascript" src="https://venue-service.tixuk.io/v4/js/venue-app.js"></script>
</body>
</html>- This will display the Seat Plan widget, allowing users to select some seats. Doing so will display details of the selected seat and provide a button to add these to their basket, like so:
In case the seat chart is not available or cannot be rendered, widget will render Seat List view
Supported data attributes
In addition to the standard data attributes used by all widgets, the following data attributes are used to customise the behaviour of the Seat Plan widget.
Name | Mandatory | Type | Sourced from Query String | Description |
|---|---|---|---|---|
data-app | Yes | String | n/a | Indicates the host app to communicate with. It should be "venue-app" |
data-api-path | Yes | String | n/a | The host for the data service to use. This should be the fully qualified domain for the relevant capability service. Example: https://venue-service.tixuk.io/ |
data-channel-id | Yes | String | n/a | The id of the affiliate for which the embedding context (i.e. website) belongs. |
data-performance-date | Yes* | Date | date | Date of the performance in the format YYYY-MM-DD e.g. 2019-01-10. *Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs. |
data-performance-time | Yes* | Time | slot | Start time of the performance in 24-hour format HH:MM e.g. 19:30. *Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs. |
data-product-id | Yes* | Number | product_id | Identifier of the product Id using for requests.
|
data-view-name | No | String | n/a | Identifies the view for the app to load. Default value - "seat-plan" |
data-performance-type | No* | String | performance_type | Indicates the type of performance, based on the part of day. Valid values are:
*Data-attr can be omitted in favour of property being supplied via query string. Query string values override data-attrs. |
data-product-id-for-content | No* | Number | content_product_id | Identifier of the product for content-service api calls. Default value: data-product-id *Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs. |
data-product-type | No* | String | product_type | Valid values are:
*Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs. |
data-quantity | No* | Number | qt | Number of tickets to be selected e.g. "2". *Data-attr can be omitted in favor of property being supplied via query string. Query string values override data-attrs. |
data-suppress-addtobasket | No | Boolean | n/a | Suppresses the redirection on add to basket CTA to allow custom handling of users selected ticket data. Default value: Event: venue-app_selected-seats-summary-on-addtobasket |
data-without-seat-summary | No | Boolean | n/a | Prevent displaying seat summary on seat selection. |
data-user-locale | No | String | n/a | Identifies user locale for labels from data-labels-config. Used to format prices for custom currencies ('en-GB' used by default). |
data-labels-config | No | String (JSON Object) | n/a | Identifies user labels. |
data-hide-spinner | No | Boolean | n/a | Hides loading spinner. |
data-use-external-availability | No | Boolean | n/a | Uses external availability. |
data-hide-price-decimals | No | Boolean | n/a | Hide decimal part from prices. |
data-defer-rendering | No | Boolean | n/a | Defer rendering until user call venue-app_render event. Example: window.dispatchEvent(new CustomEvent('venue-app_render')) |
data-disable-seat-plan-height-calculation | No | Boolean | n/a | Disable automatic Seat Plan height calculation |
data-inventory-api-url | No | String | n/a | Set custom API URL for inventory service. Example: https://inventory-service.tixuk.io/api/vLatest |
data-venue-api-url | No | String | n/a | Set custom API URL for content service. Example: https://content-service.tixuk.io/api/vLatest |
data-basket-api-url | No | String | n/a | Set custom API URL for basket service. Example: https://basket-service.tixuk.io/api/vLatest |
General Admission Tickets
Important NoteA single show can have both PYOS (Pick your own seats) and General Admission seats available. The event details will reflect the type of seat selected.
The widget now supports the selection of General Admission (GA) tickets. GA areas are identified by a mode: 'freesell' attribute, in contrast to seated areas which have mode: 'allocated'. When selecting tickets in a GA area, the seat information might display "General Admission" instead of a specific row number.
Price Overrides
The widget allows for dynamic price overrides. This is achieved by intercepting the pricing data before it's displayed and applying custom modifications.
How it works:
- Fetch Area Data: A custom function (e.g.,
priceValueOverrideas seen in the example) makes an API call to retrieve the area and grouping information for a specific product, performance date, and time.- Example API call:
GET /products/{productId}/areas?quantity={quantity}&date={performanceDate}&time={formattedPerformanceTime}
- Example API call:
- Iterate and Modify Groupings: The function then iterates through the
areasand theirgroupings. For eachgroup, it extracts the originalsalePrice. - Apply Price Modifier: A
priceModifierfunction can be applied to the original price. This function takes the original price as an argument and returns the new, modified price.- Example
priceModifier:(price) => price * 1.1(increase the price by 10%).
- Example
- Construct Override Object: An
overrideObjectis created for each modified group. This object includes:groupIdentifier: Unique identifier for the group.pricing: An object containing the modifiedsalePrice,faceValue, and optionallypromotionLabel,noBookingFee,percentageDiscount, andincludesBookingFee.
- Apply Overrides to Widget: The
priceOverridesList(an array ofoverrideObjects) is then passed to the widget usingwindow.encoreSeatWidget.onGetOverridePriceGroups(data). This method instructs the widget to use the provided overridden prices for the specified groups.
Listening to custom events
The following events are raised by the SeatPlan widget:
| Event | Description |
|---|---|
venue-app_data-attributes-validation-failed | Raised when there is a validation error with the data attributes. |
venue-app_selected-seats-summary-on-addtobasket | Raised on add to basket submission. |
venue-app_on-seats-selection-change | Raised when the user changes the seat selection. |
venue-app_on-seats-deselection | Raised when the user deselects all seats. |
venue-app_exception | Raised when an exception occurs in the application. |
How to Use These Events
All custom events dispatched by the widget will have type (the event name) and timeStamp (the time the event was created) properties available directly on the event object (e), in addition to the detail object. These events can be used to track user interactions, update the UI dynamically, or trigger other application logic. Below is a detailed explanation of each event, its purpose, and the data it provides.
-
venue-app_data-attributes-validation-failed- Purpose: This event is triggered when there is an error validating the data attributes passed to the widget.
- Data: The
detailobject contains information about the validation error:- {
"type": "error",
"errorTitle": "Data-attribute configured incorrectly",
"errorMessage": "data-quantity or qt url parameter should be in the range 1 - 10",
"errorId": "Data-attribute configured incorrectly: data-quantity or qt url parameter should be in the range 1 - 10"
}
- {
- Usage Example:
window.addEventListener("venue-app_data-attributes-validation-failed", function(e) { console.log("Data attributes validation failed:", e.detail); });
-
venue-app_selected-seats-summary-on-addtobasket-
Purpose: This event is triggered when the user clicks the "Add to Basket" button in the seat summary.
-
Data: The
detailobject contains the selected seats (selectedElement) and performance parameters (performanceParams). The structure ofselectedElementwill differ depending on whether the selection is for PYOS or General Admission seats. -
detailobject properties:-
selectedElement: An array of objects, where each object represents a single selected seat.Note: The structure of the seat objects within
selectedElementis identical to the structure of objects in theselectedSeatsarray of thevenue-app_on-seats-selection-changeevent.id: Unique identifier for the seat. For PYOS seats, this is per-seat (e.g., 'BLOCK E-C-13'). For General Admission, this is the same for all seats in the area (e.g., 'DANCE FLOOR-General Admission').groupName: The group name of the seat (e.g., 'BLOCK E' or 'DANCE FLOOR').row: The row of the seat (e.g., 'C' for PYOS, 'General Admission' for General Admission).number: The seat number. For PYOS seats, this is the actual seat number (e.g.,13). For General Admission, it is a sequential number from 1 up to the quantity of tickets requested (e.g.,1,2,3, ...).lump: An object defining the start and end seat numbers of the lump.listOfAvailableLumps: An array of available lump options.faceValue: The original face value of the ticket.salePrice: The selling price of the ticket.percentageDiscount: The percentage discount applied.faceCurrency: The currency of the face value.currency: The currency of the sale price.faceDecimalPlaces: Number of decimal places for face currency.decimalPlaces: Number of decimal places for currency.hideFaceValue: Boolean indicating if face value is hidden.hideDiscount: Boolean indicating if discount is hidden.promotionLabel: Label for any promotion.restrictedView: Boolean indicating if the seat has a restricted view.includesBookingFee: Boolean indicating if booking fee is included.seatKey: A unique key for the seat (e.g.,"eyJ0eXAiOiJKV1Qi...").category: An object containingvalueandprice.attributes: An array of seat attributes.seatIdentifier: A unique identifier for the seat (e.g.,BLOCK_E-C13or"eyJ0eXAiOiJKV1Qi...-1").aggregateReference: A reference for the aggregated seats (e.g.,"eyJ0eXAiOiJKV1Qi...").displayCurrency: The currency for display.orderFee: An object withvalue,currency, anddecimalPlaces.
-
performanceParams: An object containing parameters related to the performance:channelId: The channel identifier (e.g., 'viatorwhitelabel').productId: The product ID (e.g., '25118').productType: The product type (e.g., 'A').venueId: The venue ID (e.g., '846').performanceType: The performance type (e.g., 'A').performanceDate: The date of the performance (e.g., '2026-01-23').performanceTime: The time of the performance (e.g., '19:45').quantity: The quantity of seats (e.g., '2').productIdForContent: Product ID for content (e.g., '25118').viewName: The view name (e.g., 'seat-plan').
-
Key Differences: General Admission vs. PYOS (Pick your own seats)-
Selection Granularity:
- General Admission: While each ticket is an object in the
selectedElementarray, they share a commonidandrow, representing a selection within a general area rather than a specific, unique seat. - PYOS: Each object in the
selectedElementarray represents a unique, specific seat with its ownid,row, andnumber.
- General Admission: While each ticket is an object in the
-
Identification:
- General Admission: Seats are identified by their
groupNameandnumberwithin theGeneral Admissionrow. - PYOS: Each seat is individually identified by its unique
id(e.g., 'BLOCK E-C-13'),row, andnumber.
- General Admission: Seats are identified by their
-
Usage Example:
window.addEventListener("venue-app_selected-seats-summary-on-addtobasket", function(e) { console.log("Seats added to basket:", e.detail); // Example of logging each seat's details to a hypothetical logging system e.detail.selectedElement.forEach(seat => { console.log(`Seat added to basket: ID: ${seat.id}, Row: ${seat.row}, Number: ${seat.number}, Price: ${seat.salePrice} ${seat.currency}`); // PYOS: Seat added to basket: ID: BLOCK E-C-14, Row: C, Number: 14, Price: 110 EUR // General Admission: Seat added to basket: ID: DANCE FLOOR-General Admission, Row: General Admission, Number: 2, Price: 86.9 EUR }); const params = e.detail.performanceParams; console.log(`Performance: ${params.productId}, Date: ${params.performanceDate}, Time: ${params.performanceTime}`); // Performance: 25118, Date: 2026-01-23, Time: 19:45 });
-
-
venue-app_on-seats-selection-change-
Purpose: This event is triggered whenever the user's seat selection changes. This can happen when they select a seat, change their selection, or deselect all seats.
-
Data: The
detailobject contains aselectedSeatsarray and aselectedCategoryobject. The structure of these is consistent, but the values within will differ depending on whether the selection is for PYOS or General Admission seats. -
detailobject properties:-
selectedCategory: An object containing details about the price category of the selection.category: The category ID.price: The price of the category.salePrice: The sale price of the category.faceValue: The face value of the category.faceCurrency: The currency of the face value (e.g., 'EUR').currency: The currency of the sale price (e.g., 'EUR').faceDecimalPlaces: Number of decimal places for face currency.decimalPlaces: Number of decimal places for currency.percentageDiscount: The percentage discount applied.includesBookingFee: Boolean indicating if booking fee is included.restrictedView: Boolean indicating if the category has restricted view seats.color: The color associated with the category.borderColor: The border color associated with the category.hideFaceValue: Boolean indicating if face value is hidden.hideDiscount: Boolean indicating if discount is hidden.orderFee: An object withvalue,currency, anddecimalPlaces.promotionLabel: Label for any promotion (e.g., 'Christmas Promo').
-
selectedSeats: An array of objects, where each object represents a single selected seat.Note: The structure of the seat objects within
selectedSeatsis identical to the structure of objects in theselectedElementarray of thevenue-app_selected-seats-summary-on-addtobasketevent.id: Unique identifier for the seat. For PYOS seats, this is per-seat (e.g., 'BLOCK E-C-13'). For General Admission, this is the same for all seats in the area (e.g., 'DANCE FLOOR-General Admission').groupName: The group name of the seat (e.g., 'BLOCK E' or 'DANCE FLOOR').row: The row of the seat (e.g., 'C' for PYOS, 'General Admission' for General Admission).number: The seat number. For PYOS seats, this is the actual seat number (e.g.,13). For General Admission, it is a sequential number from 1 up to the quantity of tickets requested (e.g.,1,2,3, ...).lump: An object defining the start and end seat numbers of the lump.listOfAvailableLumps: An array of available lump options.faceValue: The original face value of the ticket.salePrice: The selling price of the ticket.percentageDiscount: The percentage discount applied.faceCurrency: The currency of the face value.currency: The currency of the sale price.faceDecimalPlaces: Number of decimal places for face currency.decimalPlaces: Number of decimal places for currency.hideFaceValue: Boolean indicating if face value is hidden.hideDiscount: Boolean indicating if discount is hidden.promotionLabel: Label for any promotion.restrictedView: Boolean indicating if the seat has a restricted view.includesBookingFee: Boolean indicating if booking fee is included.seatKey: A unique key for the seat (e.g.,"eyJ0eXAiOiJKV1Qi...").category: An object containingvalueandprice.attributes: An array of seat attributes.seatIdentifier: A unique identifier for the seat (e.g.,BLOCK_E-C13or"eyJ0eXAiOiJKV1Qi...-1").aggregateReference: A reference for the aggregated seats (e.g.,"eyJ0eXAiOiJKV1Qi...").displayCurrency: The currency for display.orderFee: An object withvalue,currency, anddecimalPlaces.
-
Key Differences: General Admission vs. PYOS (Pick your own seats)-
Selection Granularity:
- General Admission: While each ticket is an object in the
selectedSeatsarray, they share a commonidandrow, representing a selection within a general area rather than a specific, unique seat. - PYOS: Each object in the
selectedSeatsarray represents a unique, specific seat with its ownid,row, andnumber.
- General Admission: While each ticket is an object in the
-
Identification:
- General Admission: Seats are identified by their
groupNameandnumberwithin theGeneral Admissionrow. - PYOS: Each seat is individually identified by its unique
id(e.g., 'BLOCK E-C-13'),row, andnumber.
- General Admission: Seats are identified by their
Usage Example:
window.addEventListener("venue-app_on-seats-selection-change", function(e) { e.detail.selectedSeats.forEach(seat => { console.log(`Seat selection changed: ID: ${seat.id}, Row: ${seat.row}, Number: ${seat.number}, Price: ${seat.salePrice} ${seat.currency}`); // PYOS: Seat selection changed: ID: BLOCK E-C-14, Row: C, Number: 14, Price: 110 EUR // General Admission: Seat selection changed: ID: DANCE FLOOR-General Admission, Row: General Admission, Number: 2, Price: 86.9 EUR }); }); -
-
venue-app_on-seats-deselection- Purpose: This event is triggered when a user clicks "Make a different selection" button. It is not triggered when selection is changed otherwise.
- Data: The
detailobject is empty ({}). - Usage Example:
window.addEventListener("venue-app_on-seats-deselection", function(e) { console.log("All seats deselected"); });
-
venue-app_exception- Purpose: This event is triggered when an exception occurs in the application.
- Data: The
detailobject contains information about the exception, including: type: The type of the error (e.g., 'warning').errorTitle: A title for the error (e.g., 'Unable to get basket').errorMessage: A detailed message about the error (e.g., 'The basket with reference [TTG11111111] was expired.').errorId: A unique identifier for the error (e.g., 'Get basket: The basket with reference [TTG11111111] was expired.').- Usage Example:
window.addEventListener("venue-app_exception", function(e) { console.log("Exception occurred:", e.detail); });
Configuring labels
The Seat Plan widget comes with some default text labels, but these can be customized to your liking. To do so, use the "data-labels-config" attribute, like so:
<div
data-app="venue-app"
data-view-name="seat-plan"
data-channel-id="encoretickets"
data-product-id="1587"
data-product-type="show"
data-performance-type="A"
data-performance-date="2020-03-21"
data-performance-time="19:30"
data-quantity="2"
data-api-path="http://encoretickets.co.uk"
data-redirect-url=""
data-user-locale="en-GB"
data-labels-config='{
"seatList":{
"findingAvailability":{
"en-GB":"Finding Availability",
"it-IT":"Trovare disponibilità"
},
"reservingSelection":{
"en-GB": "Reserving Selection",
"it-IT": "Selezione della prenotazione"
}
},
"seatSummary":{
"seats":{
"en-GB":"Seats",
"it-IT":"Sedili"
},
"restrictedView":{
"en-GB":"Restricted view",
"it-IT":"Visione limitata"
},
"sideView":{
"en-GB":"Side view",
"it-IT":"Vista laterale"
},
"seatPrice":{
"en-GB":"Seat price",
"it-IT":"Prezzo del posto"
},
"noBookingFee":{
"en-GB":"No booking fee",
"it-IT":"Nessuna commissione di prenotazione"
},
"addToBasket":{
"en-GB":"Add to basket",
"it-IT":"Aggiungi al carrello"
}
},
"legend":{
"restrictedView":{
"en-GB":"Restricted view",
"it-IT":"Visione limitata"
},
"offer":{
"en-GB":"Offer",
"it-IT":"Offrire"
},
"restrictedViewOffer":{
"en-GB":"Restricted view & offer",
"it-IT":"Offerta e vista riservata"
},
"noFees":{
"en-GB":"No fees",
"it-IT":"Senza tasse"
}
},
"seatPlan":{
"notAvailable":{
"en-GB":"notAvailable",
"it-IT":"Non disponibile"
},
"sectionAvailability.none":{
"en-GB":"sectionAvailability.none",
"it-IT":"Nessun posto disponibile"
},
"clickToSelect":{
"en-GB":"clickToSelect",
"it-IT":"Clic per selezionare"
},
"clickToDeselect":{
"en-GB":"clickToDeselect",
"it-IT":"Clic per deselezionare"
},
"row":{
"en-GB":"row",
"it-IT":"riga"
},
"seat":{
"en-GB":"seat",
"it-IT":"sedia"
},
"table":{
"en-GB":"table",
"it-IT":"Tavola"
},
"section":{
"en-GB":"section",
"it-IT":"Section"
},
"restrictedView":{
"en-GB":"restrictedView",
"it-IT":"Visione limitata"
},
"couch":{
"en-GB":"Couch",
"it-IT":"Divano"
},
"bar":{
"en-GB":"Bar",
"it-IT":"Bar"
}
}
}' />seatList -> findingAvailability
Spinner message showing during availability data loading
seatList -> reservingSelection
Spinner message showing during basket reservation process
seatSummary -> seats
Seats label
seatSummary -> restrictedView
Restricted view label
seatSummary -> sideView
Side view restriction
seatSummary -> seatPrice
Seat Price label
seatSummary -> noBookingFee
No Booking Fee label
seatSummary -> addToBasket
Add to Basket button text
legend -> restrictedView
Restricted View label in legend
legend -> offer
Offer label in legend
legend -> restrictedViewOffer
Offer & Restricted View label in legend
legend -> noFees
No fees label in legend
seatPlan -> notAvailable
Not Available label in seat plan tooltip
seatPlan -> sectionAvailability.none
No seats available label in section popup when no seats for section available
seatPlan -> clickToSelect
Click to Select label in seat plan tooltip
seatPlan -> clickToDeselect
Click to Deselect label in seat plan tooltip
seatPlan -> row
Row label in seat plan tooltip
seatPlan -> seat
Seat label in seat plan tooltip
seatPlan -> table
Table label in seat plan tooltip
seatPlan -> section
Section label in seat plan tooltip
seatPlan -> restrictedView
Restricted View label in seat plan tooltip
seatPlan -> couch
Couch label in seat plan tooltip
seatPlan -> bar
Bar label in seat plan tooltip