Skip to content
Docs
Quickstart

HTML quickstart

A single HTML file that lists events, sells tickets through the hosted checkout and shows the order. No build step.

One file, no build tools. Works the same inside Webflow, Framer, Squarespace or any site builder that lets you add a script tag and custom HTML.

What you need#

  • A publishable key (tlpk_...) for a sales channel. See Get a key.
  • At least one event listed on that channel (in Backstage: the event's listing on the channel, with an occurrence and a price scheme on sale).

The page#

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Tickets</title>
  <script src="https://cdn.ticketlayer.com/v1/ticketlayer.js"
          data-publishable-key="tlpk_..."
          data-api-url="https://live.ticketlayer.com"
          data-checkout-base="https://checkout.ticketlayer.com"
          data-elements-url="https://cdn.ticketlayer.com/elements/v1/ticketlayer-elements/ticketlayer-elements.esm.js"></script>
  <style>
    /* Theme tokens: the channel theme sets these; override any of them. */
    :root { --tl-primary: #0f766e; --tl-radius-md: 0.375rem; }
    body { font-family: system-ui, sans-serif; max-width: 960px; margin: 2rem auto; }
    header { display: flex; justify-content: space-between; align-items: center; }
  </style>
</head>
<body>
  <header>
    <h1>What's on</h1>
    <tl-cart-badge></tl-cart-badge>
  </header>

  <!-- Lists the channel's events. Clicking a card emits tlEventClick. -->
  <tl-event-list columns="3" limit="12"></tl-event-list>

  <!-- A buy button for one specific event opens the buy flow directly. -->
  <h2>Featured</h2>
  <tl-buy-tickets-button event-id="evt_..." size="lg"></tl-buy-tickets-button>

  <!-- The cart panel; opens when the badge is clicked. -->
  <tl-cart-drawer></tl-cart-drawer>

  <script>
    // Elements dispatch CustomEvents named tl*; the payload is event.detail.
    document.querySelector('tl-event-list').addEventListener('tlEventClick', (e) => {
      console.log('event clicked', e.detail.eventId);
    });

    // The loader exposes the Live client once it has booted.
    window.ticketlayer.ready.then((tl) => {
      if (!tl) return; // no key, or boot failed (see the console)
      tl.on('checkout:completed', (order) => {
        // The hosted checkout finished. Send the customer to a thank-you page
        // that mounts <tl-order-confirmation>, which reads ?orderId= itself.
        location.href = '/thanks.html?orderId=' + encodeURIComponent(order.id);
      });
    });
  </script>
</body>
</html>

And thanks.html, with the same script tag in its head:

<tl-order-confirmation></tl-order-confirmation>

What each line does#

PieceBehaviour
The script tagBoots a Live client from its data-* attributes, publishes it on window.Ticketlayer for the elements, injects the Elements bundle, installs the buy modal and the hosted checkout modal. Idempotent; a no-op without a key.
<tl-event-list>Fetches the channel's listings and renders a card per event. Attributes: columns, limit, category. Event: tlEventClick with { eventId }.
<tl-buy-tickets-button>Emits tlClick and opens the buy modal (date, then tickets) for event-id. Attributes include occurrence-id, label, price, state, variant, size.
<tl-cart-badge> and <tl-cart-drawer>The badge shows the item count and opens the drawer; the drawer holds <tl-cart> with a Checkout button that opens the hosted checkout.
checkout:completedEmitted on the Live client when the checkout iframe reports success. The payload is the order (id, orderNumber).
<tl-order-confirmation>Order reference, lines, totals and the tickets with QR codes and PDF links. Finds the order from order-id, then ?orderId= in the URL, then the checkout:completed event.

Next#