Skip to content
Docs
Reference

Elements

The Ticketlayer Elements: web components that list events, sell tickets and show orders on any page, plus the theme tokens they read.

Elements are web components (custom HTML tags prefixed tl-) that list events, take a customer through ticket selection, cart and checkout, and show the tickets they bought. They work in plain HTML, in Webflow or any site builder that lets you add a script tag, and in React through the generated wrappers in @ticketlayer/elements-react.

Every element binds to the Live client the page publishes on window.Ticketlayer. Elements take no API key of their own: create the client once (the CDN loader does this from its data-* attributes, or call createLiveClient() from @ticketlayer/live) and the elements find it.

Get them onto the page#

CDN, no build step. One script tag loads the Live SDK, the Elements bundle and the hosted checkout modal. The tags below then just work.

<script src="https://cdn.ticketlayer.com/v1/ticketlayer.js"
        data-publishable-key="tlpk_..."
        data-api-url="live.ticketlayer.com"
        data-checkout-base="checkout.ticketlayer.com"></script>

<tl-event-list columns="3"></tl-event-list>

See the HTML quickstart for the attributes each environment needs today.

npm, for React and bundlers.

npm install @ticketlayer/live @ticketlayer/elements @ticketlayer/elements-react
import { createLiveClient } from '@ticketlayer/live';
import { defineCustomElements, TlEventList } from '@ticketlayer/elements-react';

defineCustomElements(); // once, after hydration
await createLiveClient({ baseUrl: 'live.ticketlayer.com', publishableKey: 'tlpk_...' });

<TlEventList columns={3} onTlEventClick={(e) => console.log(e.detail.eventId)} />

:::note Package status @ticketlayer/live, @ticketlayer/elements and @ticketlayer/elements-react are built in their repositories but are not on the public npm registry yet; they publish once their release workflows run. Until then use the CDN build, which is served at cdn.ticketlayer.com. See the Vite quickstart for the workaround in the meantime. :::

Elements#

Discovery#

List and present events.

ElementReactWhat it does
<tl-event-card>TlEventCardOne event as a card: its image, name, next date, venue, what a ticket costs with fees, and how it is selling.
<tl-event-list>TlEventListWhat the channel is selling, as a grid of event cards, optionally narrowed to one category.
<tl-occurrence-selector>TlOccurrenceSelectorA smart occurrence selector component that fetches and displays event occurrences from the Ticketlayer API.

Purchase#

Choose a date, pick tickets, open the buy flow.

ElementReactWhat it does
<tl-best-available>TlBestAvailableThe best seats for a party: a few options that differ (the best, a cheaper one, one closer or further back), each with the view from it, the row and seats, why it was chosen and the price.
<tl-buy-modal>TlBuyModalThe buy-tickets modal: a date, then tickets, then payment, under a header carrying the channel's and the event's identity, beside a basket showing what the buyer is paying for.
<tl-buy-tickets-button>TlBuyTicketsButtonA buy-tickets button in one of four sale states, which opens the purchase modal.
<tl-buy-tickets-wrapper>TlBuyTicketsWrapperWrap any content and open the purchase modal when it is activated.
<tl-gift-card-shop>TlGiftCardShopBuy a gift card: choose the card, an amount it comes in, email or post (post only with a posted order), the recipient and a message, and add it to the basket.
<tl-map-key>TlMapKeyThe seat map's key: a minimap of the whole venue with the part the map shows outlined (choose a section to go there), and the price bands, each category's colour and lowest price, with the seat states
<tl-price-picker>TlPricePickerThe ticket type of a held seat: Adult, Child, Concession and the rest of its category's types, as a dropdown or a segmented control, for one seat or every seat held for the occurrence.
<tl-promo-code>TlPromoCodeApply a code to the current cart: what it unlocks, discounts or waives is that cart's and its order's.
<tl-quantity-picker>TlQuantityPickerHow many tickets: square buttons 1 to 5 and a 6+ dropdown up to the channel's limit, or a keypad for staff.
<tl-seat-card>TlSeatCardOne seat as a card: the view from it when there are views, the row and number, the section, the price, whether it is free or held, and for a held seat its ticket type to change.
<tl-seat-explorer>TlSeatExplorerThe seat map: the venue's sections, flown into one at a time, and its seats in their categories' colours.
<tl-seat-preferences>TlSeatPreferencesWhat a party prefers beyond how many: a price per ticket, an area, an aisle seat, wheelchair spaces and how together.
<tl-seat-view>TlSeatViewThe view from one seat, or from a block of seats, in a box a little smaller than what it sits over, dimming it: the rendered still and a 360 look around its row where the venue has them, else the near
<tl-ticket-selector>TlTicketSelectorPick quantities of the ticket types on sale for one occurrence, priced with every fee in them, and add them to the cart.

Cart#

Show and edit what the customer is about to buy.

ElementReactWhat it does
<tl-cart>TlCartThe buyer's cart: its lines, the money rows the surface reported and a checkout button.
<tl-cart-badge>TlCartBadgeA cart icon carrying the number of items in the cart, kept current from the cart bus.
<tl-cart-drawer>TlCartDrawerA slide-in panel holding the cart, opened by the cart intent on the client bus.

Checkout#

Hand off to the hosted checkout and confirm the order.

ElementReactWhat it does
<tl-checkout-credit>TlCheckoutCreditThe checkout's gift cards and credit: apply the signed-in buyer's account credit, or a gift card by its code, see what each covers, and remove either before paying.
<tl-checkout-holders>TlCheckoutHoldersThe checkout's "Who is this for?" section: a name for each guest, vehicle or group the cart makes, and who each add-on goes to, "one each" when that is automatic.
<tl-checkout-summary>TlCheckoutSummaryThe checkout's order summary, priced from the cart's quote: the tickets with the fees included in them, each separate fee, any discount and the total checkout charges.
<tl-checkout-wrapper>TlCheckoutWrapperWrap any content and open the checkout modal when it is activated.
<tl-delivery-picker>TlDeliveryPickerThe checkout's Delivery section: how the tickets reach the buyer, each method with what it adds, and the reason beside one that cannot be chosen.
<tl-order-confirmation>TlOrderConfirmationThe thank-you block: order reference, email, event and date, the ticket lines, the money rows and the tickets.
<tl-payment-picker>TlPaymentPickerThe checkout's Payment section: the ways this order can be paid, each with any surcharge it adds, and the reason beside one that cannot be chosen.

Tickets#

Render issued tickets with QR codes and PDF downloads.

ElementReactWhat it does
<tl-booking-pass>TlBookingPassThe booking pass: one barcode for the whole order, listing everyone it covers until each has their own pass or wristband.
<tl-holder-pass>TlHolderPassA named guest's own page, from the link the booker sent: their ticket and extras, their name under the event's rules, and their own pass to download.
<tl-order-tickets>TlOrderTicketsEvery ticket in an order as a scannable card, waiting out issuance rather than reporting an empty order as empty.
<tl-ticket>TlTicketA single issued ticket: a scannable QR, its name, seat and holder, and a PDF download.
<tl-wristband-activate>TlWristbandActivateActivate a wristband that came in the post by tapping it on the phone (Web NFC where the browser has it); where it cannot, explains the desk at the event instead.

Account#

Sign in with a magic link and show past orders.

ElementReactWhat it does
<tl-booking-holders>TlBookingHoldersManage my booking, people first: each holder with their ticket and add-ons, to name or rename, move an add-on to someone else, place add-ons nobody has yet, and activate a posted wristband.
<tl-gift-card-balance>TlGiftCardBalanceCheck what is on a gift card by its code: the amount, until when, and whether it can be used.
<tl-login>TlLoginMagic-link sign-in: an email in, a link or a six-digit code back, and a session.
<tl-my-credit>TlMyCreditYour credit: the signed-in buyer's account credit with this organisation, each balance with its expiry and whether it is on hold, and its activity (what was put on it and spent, when, and on which ord
<tl-my-orders>TlMyOrdersThe signed-in customer's orders: event, date, ticket count, total and status, each row expanding to its tickets.
<tl-refund-request>TlRefundRequestAsk for a refund on an order, with a reason and where the money should go: back the way it was paid, or as account credit.

Other#

ElementReactWhat it does
<tl-concierge>TlConciergeConcierge: search the help articles, ask the AI when the channel has it on, see my orders after a code typed into the widget, or contact the organiser.
<tl-concierge-slot>TlConciergeSlotThe "Need help?" another element hosts: renders nothing unless the channel has Concierge on for that placement, then a help field that opens tl-concierge inline with the host's context and what was ty

Events#

Every element emits CustomEvents whose names start with tl and whose payload is on event.detail. In HTML:

<tl-event-list></tl-event-list>
<script>
  document.querySelector('tl-event-list').addEventListener('tlEventClick', (e) => {
    location.href = '/events/' + e.detail.eventId;
  });
</script>

In React each event is a prop named onTl...: <TlEventList onTlEventClick={(e) => ...} />.

Theming#

Elements read CSS custom properties prefixed --tl-. The Live SDK injects the values of the channel's theme (configured in Backstage) when applyTheme is on, which it is by default; set any token yourself on :root or on a wrapper to override. The defaults below come from the Elements global stylesheet and apply when nothing else sets the token.

Colour#

Palette.

TokenDefault
--tl-primary#4f46e5
--tl-color-primaryvar(--tl-primary)
--tl-primary-foreground#ffffff
--tl-color-primary-foregroundvar(--tl-primary-foreground)
--tl-secondary#f3f4f6
--tl-color-secondaryvar(--tl-secondary)
--tl-secondary-foreground#111827
--tl-color-secondary-foregroundvar(--tl-secondary-foreground)
--tl-accent#ec4899
--tl-color-accentvar(--tl-accent)
--tl-accent-foreground#111827
--tl-color-accent-foregroundvar(--tl-accent-foreground)
--tl-background#ffffff
--tl-color-backgroundvar(--tl-background)
--tl-foreground#111827
--tl-color-foregroundvar(--tl-foreground)
--tl-cardvar(--tl-background)
--tl-color-cardvar(--tl-card)
--tl-muted#f9fafb
--tl-color-mutedvar(--tl-muted)
--tl-muted-foreground#6b7280
--tl-color-muted-foregroundvar(--tl-muted-foreground)
--tl-border#e5e7eb
--tl-color-bordervar(--tl-border)
--tl-border-hovercolor-mix(in srgb, var(--tl-foreground) 35%, var(--tl-border))
--tl-color-border-hovervar(--tl-border-hover)
--tl-input#e5e7eb
--tl-color-inputvar(--tl-input)
--tl-ring#4f46e5
--tl-color-ringvar(--tl-ring)
--tl-success#10b981
--tl-color-successvar(--tl-success)
--tl-success-foreground#111827
--tl-color-success-foregroundvar(--tl-success-foreground)
--tl-warning#f59e0b
--tl-color-warningvar(--tl-warning)
--tl-warning-foreground#111827
--tl-color-warning-foregroundvar(--tl-warning-foreground)
--tl-warning-bgcolor-mix(in srgb, var(--tl-warning) 15%, var(--tl-background))
--tl-color-warning-bgvar(--tl-warning-bg)
--tl-error#dc2626
--tl-color-errorvar(--tl-error)
--tl-destructivevar(--tl-error)
--tl-color-destructivevar(--tl-error)
--tl-error-foreground#ffffff
--tl-color-error-foregroundvar(--tl-error-foreground)
--tl-destructive-foregroundvar(--tl-error-foreground)
--tl-color-destructive-foregroundvar(--tl-error-foreground)
--tl-error-bgcolor-mix(in srgb, var(--tl-error) 12%, var(--tl-background))
--tl-color-error-bgvar(--tl-error-bg)
--tl-destructive-bgvar(--tl-error-bg)
--tl-color-destructive-bgvar(--tl-error-bg)
--tl-info#3b82f6
--tl-color-infovar(--tl-info)
--tl-info-foreground#ffffff
--tl-color-info-foregroundvar(--tl-info-foreground)
--tl-info-bgcolor-mix(in srgb, var(--tl-info) 14%, var(--tl-background))
--tl-color-info-bgvar(--tl-info-bg)
--tl-overlaycolor-mix(in srgb, color-mix(in srgb, var(--tl-background) 22%, #000000) 55%, transparent)

Type#

Font stacks, the base size and ratio, and the type scale derived from them.

TokenDefault
--tl-font-familysystem-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif
--tl-font-family-headingvar(--tl-font-family)
--tl-font-weight-heading600
--tl-font-family-monoui-monospace, SFMono-Regular, 'SF Mono', Menlo, monospace
--tl-font-size-base16px
--tl-base-sizevar(--tl-font-size-base)
--tl-font-scale1.25
--tl-font-size-2xscalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), -1.5))
--tl-font-size-xscalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), -1))
--tl-font-size-smcalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), -0.5))
--tl-font-size-mdvar(--tl-font-size-base)
--tl-font-size-lgcalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), 0.5))
--tl-font-size-xlcalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), 1))
--tl-font-size-2xlcalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), 2))
--tl-font-size-3xlcalc(var(--tl-font-size-base) * pow(var(--tl-font-scale), 3))

Radius#

Corner radii.

TokenDefault
--tl-radius-none0px
--tl-radius-sm0.25rem
--tl-radius-md0.5rem
--tl-radiusvar(--tl-radius-md)
--tl-radius-lg0.75rem
--tl-radius-full9999px

Spacing#

The spacing step scale.

TokenDefault
--tl-spacing-10.25rem
--tl-spacing-20.5rem
--tl-spacing-30.75rem
--tl-spacing-41rem
--tl-spacing-51.25rem
--tl-spacing-61.5rem
--tl-spacing-82rem

Motion#

Durations and easings.

TokenDefault
--tl-duration-fast120ms
--tl-duration-normal200ms
--tl-duration-slow320ms
--tl-easing-standardcubic-bezier(0.2, 0, 0, 1)
--tl-easing-emphasisedcubic-bezier(0.3, 0, 0, 1)

Seat map#

The seat map: the map itself (map-*: background, plates, sections, labels, pins), the stage (stage-*) and the seats (seat-*: each state, the selected seat on the brand colour, the hover ring and the sizes they are drawn at).

TokenDefault
--tl-map-background#f4f4f5
--tl-map-plate#ffffff
--tl-map-section#ececef
--tl-map-section-outline#a1a1aa
--tl-stage-fill#e4e4e7
--tl-stage-edge#d4d4d8
--tl-stage-label#52525b
--tl-map-label#52525b
--tl-map-pillar#a1a1aa
--tl-map-pillar-edge#71717a
--tl-map-aisle#fafafa
--tl-map-aisle-line#a1a1aa
--tl-seat-availablevar(--tl-primary)
--tl-seat-unavailable#d4d4d8
--tl-seat-killed#e4e4e7
--tl-seat-held#d97706
--tl-seat-comp#0d9488
--tl-seat-allocated#a21caf
--tl-seat-reserved#a1a1aa
--tl-seat-selectedvar(--tl-primary)
--tl-seat-selected-markvar(--tl-primary-foreground)
--tl-seat-selected-ringvar(--tl-foreground)
--tl-seat-hover-ringvar(--tl-foreground)
--tl-map-pin#ffffff
--tl-map-pin-border#e4e4e7
--tl-map-pin-textvar(--tl-foreground)
--tl-map-pin-activevar(--tl-foreground)
--tl-map-pin-active-textvar(--tl-background)
--tl-map-pin-shadow#09090b2e
--tl-seat-scale0.4
--tl-seat-unavailable-scale0.6
--tl-seat-min-radius1.2px
--tl-seat-hit-radius3px
--tl-seat-hover-ring-width1.5px
--tl-stage-radius9px
--tl-map-pin-height28px
--tl-map-label-sizevar(--tl-font-size-xs)
--tl-map-pin-font-sizevar(--tl-font-size-xs)
:root {
  --tl-primary: #0f766e;
  --tl-primary-foreground: #ffffff;
  --tl-radius-md: 0.25rem;
  --tl-font-family: 'Inter', system-ui, sans-serif;
}

Elements render in shadow DOM, so ordinary CSS selectors from the page do not reach inside them; the tokens are the styling contract.