Loader script
Load the widget once per page:
<script
type="module"
src="https://cdn.surgetix.com/surgetix-connect/latest/surgetix.js"
data-tenant="summer-fest"
data-api-url="https://api.surgetix.com"
data-turnstile-key="YOUR_TURNSTILE_SITE_KEY"
></script>
CDN paths
| Path | Cache | Use case |
|---|---|---|
/surgetix-connect/latest/surgetix.js | Short cached | Testing, staging, automatically receiving the latest deployed widget. |
/surgetix-connect/vX.Y.Z/surgetix.js | Immutable | Production pinning and controlled rollouts. |
Script attributes
| Attribute | Required | Description |
|---|---|---|
type="module" | Yes | Required because the widget ships as an ES module. |
src | Yes | CDN or local path to surgetix.js. |
data-tenant | Yes | SurgeTix tenant slug. All API requests use /api/{tenant}/…. |
data-turnstile-key | Usually | Cloudflare Turnstile site key for guest checkout. Required unless buyers always arrive with data-user-token. |
data-api-url | For CDN embeds | API origin. Use the production or staging API origin per environment. |
data-locale | No | Initial locale: en, de, fr, it. Defaults to en. |
data-user-email | No | Pre-fill checkout email. |
data-user-name | No | Optional buyer name. |
data-user-token | No | Signed JWT. Takes priority over data-user-email. |
data-stripe-key | No | Stripe publishable key override. Tenant-resolved key is used otherwise. |
data-log-endpoint | No | Widget log streaming endpoint (managed deployments). |
Mounting widgets
Declare widgets with data-surgetix="<type>" on any host element. The loader scans the initial DOM and observes later DOM insertions, so declarative widgets work on static pages and most SPAs.
Each widget gets its own Shadow DOM root. The only supported styling bridge is CSS custom properties.
<div data-surgetix="buy-button" data-event="evt_123"></div>
Widget reference
full
Complete single-event purchase flow. Renders queue, buy-button, cart and checkout stacked.
<div data-surgetix="full" data-event="evt_123"></div>
| Attribute | Required | Description |
|---|---|---|
data-event | Yes | Event ID. |
buy-button
Ticket selection control for one event. GA → quantity selector. Multiple GA categories → per-category controls. Assigned seating → "Select seats" action that scrolls to the matching seat picker.
<div data-surgetix="buy-button" data-event="evt_123"></div>
seat-picker
Interactive Canvas2D seat map. Click/tap reserves, wheel zooms, touch pans and pinches, keyboard pans and zooms. Live updates over the event WebSocket. If the API returns queue_required, the widget dispatches surgetix:queue-required.
<div data-surgetix="seat-picker" data-event="evt_123"></div>
| Attribute | Required | Description |
|---|---|---|
data-event | Yes | Event ID. |
data-read-only | No | Show availability without allowing reservations. |
cart
Shared cart for all widgets on the page. Holds ticket sessions, pass items, coupon state, countdown, and the checkout action. Pass items persist in localStorage until checkout or removal.
<div data-surgetix="cart"></div>
| Attribute | Required | Description |
|---|---|---|
data-expand-up | No | Opens the expanded cart panel upward (sticky footers). |
data-inline | No | Renders a permanently expanded inline cart panel (booking rails). |
checkout
Payment modal for the current cart. Stripe uses Payment Element when a publishable key is available. Datatrans redirect and lightbox flows are handled by the modal.
<div data-surgetix="checkout"></div>
queue
Waiting-room UI for one event. Polls position every 3 seconds, stores the queue token on admission, and lets buy-button/seat-picker attach the token to reservation requests.
<div data-surgetix="queue" data-event="evt_123"></div>
pass-card
Festival pass purchase card. Each pass type renders its own parameter form (venue, date, name on pass) when the type requires one.
<div
data-surgetix="pass-card"
data-festival-id="fest_2026"
data-pass-type-id="pass_full"></div>
coupon-input
Standalone coupon or activation-code input. The built-in cart already supports code application; use this only when the host layout needs a separate field.
gift-card-purchase
Gift-card purchase form for a pass-backed gift card. Buyer chooses amount, recipient email and optional message; goes through the standard cart and checkout.
<div
data-surgetix="gift-card-purchase"
data-festival-id="fest_2026"
data-pass-type-id="pass_gift_card"></div>
JavaScript API
When the kernel is ready, it exposes window.SurgeTix and dispatches surgetix:ready.
SurgeTix.mount(type, container, options?)
Mount a widget programmatically. Useful for SPA route-driven mounting.
SurgeTix.mount("cart", document.getElementById("cart"));
SurgeTix.mount("seat-picker", document.getElementById("seats"), {
eventId: "evt_123",
});
| Option | Maps to |
|---|---|
eventId | data-event |
passTypeId | data-pass-type-id |
festivalId | data-festival-id |
limit | data-limit |
SurgeTix.getCart()
Returns the current cart state.
const cart = SurgeTix.getCart();
console.log(cart.items, cart.passItems, cart.expiresAt);
SurgeTix.getStore()
Returns the reactive store for advanced integrations. Subscription keys include cart, checkout, identity, tenant, events, locale, turnstile, toast, lastOrder, coupons, plus event-specific keys event:{eventId}.
const store = SurgeTix.getStore();
const off = store.subscribe("cart", (cart) => console.log(cart));
off();
SurgeTix.setLocale(locale, overrides?)
Sets the active locale for all mounted widgets. Optional overrides map message keys to custom strings.
SurgeTix.setLocale("de", {
buy_add_to_cart: "Platz reservieren",
checkout_pay: "Jetzt bezahlen",
});
SurgeTix.getLocale()
Returns the current locale.
SurgeTix.removeCartItem(sessionId)
Releases one ticket reservation and removes it from the cart.
SurgeTix.openCheckout()
Opens the checkout modal unless payment is already processing or complete.
CustomEvents
All integration events are standard DOM events on document.
Dispatched by SurgeTix Connect
| Event | Detail | Description |
|---|---|---|
surgetix:ready | — | Kernel initialized, window.SurgeTix available. |
surgetix:cart-updated | { items, passItems, total, currency } | Cart changed (add, remove, restore, expiry). Total in minor units. |
surgetix:cart-expired | — | Reservation countdown reached zero. |
surgetix:order-complete | { orderId, email, items, pdf_token?, wallet_token? } | Payment completed. |
surgetix:continue | — | User clicked "continue shopping" in cart. |
surgetix:queue-required | { eventId } | Reservation blocked by waiting room. |
surgetix:queue-left | — | Buyer closed queue UI. |
surgetix:guest-token | { token } | Queue admission returned a guest JWT. |
surgetix:coupon-applied | { code, discountCents, reason } | Standalone coupon-input accepted a code. |
surgetix:coupon-rejected | { code, error } | Standalone coupon-input rejected a code. |
Consumed by SurgeTix Connect
| Event | Detail | Description |
|---|---|---|
surgetix:queue-admitted | { eventId, token } | Host queue overlay admitted the buyer. Stores the queue token for future reservations. |
surgetix:queue-films | { films } | Supplies film data for the queue carousel UI. |
surgetix:cart-changed | { action: "add-pass", … } | Advanced bridge for host-owned pass purchase controls. |
document.addEventListener("surgetix:order-complete", (e) => {
window.location.href = `/thank-you?order=${e.detail.orderId}`;
});
document.dispatchEvent(new CustomEvent("surgetix:queue-admitted", {
detail: { eventId: "evt_123", token: "queue_token_abc" },
}));
Identity modes
Guest
Default. Buyer enters email at checkout. Widget obtains a guest JWT before reservation or payment.
Simple provided
Pre-fills checkout and makes the email read-only. Still uses Turnstile because reservations require a guest JWT.
<script
type="module"
src="…/surgetix.js"
data-tenant="summer-fest"
data-turnstile-key="…"
data-user-email="[email protected]"
data-user-name="Jane Doe"
></script>
Signed JWT
Cryptographic identity, verified by the backend. No Turnstile required. Example payload:
{
"sub": "user_123",
"email": "[email protected]",
"name": "Jane Doe",
"iat": 1777382400,
"exp": 1777468800
}
Localization
| Code | Language |
|---|---|
en | English |
de | German |
fr | French |
it | Italian |
Set initial locale on the loader, change at runtime with SurgeTix.setLocale(). Prices use Intl.NumberFormat with the active locale; currency comes from the event or pass configuration.
Theming
Set CSS custom properties on a parent element or :root. They pierce Shadow DOM by design.
| Variable | Default | Controls |
|---|---|---|
--st-bg | #09090b | Base background. |
--st-bg-surface | #18181b | Cards, drawers, surface panels. |
--st-text | #fafafa | Primary text. |
--st-text-muted | #a1a1aa | Muted text. |
--st-accent | #FF6666 | Primary actions, highlights, active states. |
--st-on-accent | #09090b | Text/icons on accent backgrounds. |
--st-error | #ef4444 | Errors and expiry warnings. |
--st-success | #22c55e | Success states. |
--st-border | #27272a | Borders and dividers. |
--st-ring | var(--st-accent) | Keyboard focus ring. |
--st-radius | 8px | Border radius. |
--st-font | system-ui, sans-serif | Base font. |
--st-font-display | serif | Display font for pass and festival headings. |
--st-font-size | 14px | Base font size. |
Accessibility
SurgeTix Connect ships:
- Keyboard focus indicators inside every Shadow DOM root.
- ARIA labels and state on interactive controls.
- Live regions on cart and checkout state changes where appropriate.
- Touch targets sized for mobile use.
prefers-reduced-motion: reducedisables animations.
Host pages should still provide semantic headings, page landmarks, sufficient surrounding contrast, and a logical tab order around widget mount points.
Content Security Policy
If the host site uses CSP, allow the widget CDN, API origin, Turnstile, Stripe, and Datatrans when those features are enabled.
script-src 'self' https://cdn.surgetix.com https://challenges.cloudflare.com https://js.stripe.com;
connect-src 'self' https://api.surgetix.com https://cdn.surgetix.com;
frame-src https://challenges.cloudflare.com https://js.stripe.com;
Browser support
| Browser | Minimum |
|---|---|
| Chrome / Edge | 80+ |
| Firefox | 78+ |
| Safari / iOS Safari | 14+ |
| Samsung Internet | 13+ |
Requires ES modules, Shadow DOM, Custom Elements-compatible DOM APIs, Fetch and WebSocket. No IE11 support.
Build output
One kernel entry plus lazy-loaded chunks. Chunks load relative to surgetix.js, so they work from a CDN origin even when embedded on a third-party site.
dist/
surgetix.js
chunks/
buy-button.[hash].js
cart.[hash].js
checkout.[hash].js
seat-picker.[hash].js
queue.[hash].js
full.[hash].js
pass-card.[hash].js
coupon-input.[hash].js
gift-card-purchase.[hash].js