Skip to content

<seva-event-register>

The <seva-event-register> component provides the complete event registration flow — from viewing event details to selecting tickets, entering attendee information, and adding everything to the cart.

When loaded, the component fetches event details from the API and renders the event name, date, location, and capacity. Authenticated users can select tickets for themselves and guests, then add the registration to the cart. Unauthenticated users are prompted to sign in or (if enabled) register as a guest.

<script type="module" src="YOUR_COMPONENTS_URL/seva-event-register.js"></script>
<seva-event-register
tenant-slug="my-club"
event-slug="annual-gala"
api-url="https://api.seva.tools">
</seva-event-register>
AttributeTypeDefaultDescription
tenant-slugstring''Required. Your organization’s tenant slug.
event-slugstring''Required. The slug of the event to display.
api-urlstring'https://api.seva.tools'Base URL of the Seva API.
theme'light' | 'dark''light'Color theme. Set via JavaScript property.
auth-tokenstring | nullnullSession token from <seva-auth>. Set this attribute when a user signs in so the component can make authenticated API calls and show member pricing.
EventPayloadWhen it fires
seva:event-loaded{ event: EventDetail, tickets: TicketDetail[] }Event data has been fetched from the API.
seva:add-to-cart{ eventSlug: string, eventName: string, attendees: AttendeeInput[], guestEmail?: string, hostMemberId?: string }User clicks “Add to Cart” on the review screen. Picked up automatically by <seva-cart>.
seva:registration-error{ message: string }Failed to load event data.
seva:registration-declined{ eventSlug: string }User declines the event invitation.
seva:view-changed{ view: EventRegisterView }The component transitions between internal views.
seva:authenticated{ user: AuthUser, token: string }Fired if a stored session is found during initialization (passthrough from token manager).
interface EventDetail {
id: string;
name: string;
slug: string;
description: string | null;
location: string | null;
eventStart: string | null;
eventEnd: string | null;
guestRegistrationEnabled: boolean | null;
requireMemberHost: boolean | null;
allowGuests: boolean | null;
capacityRemaining: number | null;
}
interface TicketDetail {
id: string;
name: string;
description: string | null;
eligibility: 'member' | 'guest' | null;
resolvedPriceCents: number;
}
interface AttendeeInput {
ticketId: string;
ticketName: string;
priceCents: number;
firstName: string;
lastName: string;
email: string;
isSelf: boolean;
}
type EventRegisterView =
| 'loading' | 'event-info' | 'sign-in' | 'guest-info'
| 'member-registration' | 'tickets' | 'attendee-details'
| 'review' | 'confirmation' | 'registered' | 'declined';

The component walks the user through a multi-step flow:

  1. Event Info — Displays event name, date, location, description, and capacity badge. Shows a “Register” button (authenticated) or “Sign In to Register” (unauthenticated).

  2. Sign In (unauthenticated only) — Embeds a <seva-auth> component inline. After sign-in, the flow continues.

  3. Guest Info (unauthenticated guest only) — Collects email and optionally a host member (if requireMemberHost is enabled on the event).

  4. Member Registration (authenticated) — Shows available tickets as radio buttons. The user selects a ticket for themselves and can add guests with name, email, and ticket selection.

  5. Ticket Selection (guest flow) — Quantity-based ticket picker for eligible tickets.

  6. Attendee Details (guest flow) — Collects first name, last name, and email for each attendee.

  7. Review — Summary of all attendees, tickets, and total price. “Add to Cart” button fires seva:add-to-cart.

  8. Confirmation — Shows “Added to Cart” confirmation after the event is dispatched.

  9. Registered — Shown when an authenticated user already has a registration. Displays their ticket, any guests, and options to add more guests, or cancel the registration.

  10. Declined — Shown after the user declines an event. Offers a “Register Instead” button to undo.

The component listens for these events on document:

EventBehavior
seva:authenticatedStores the token and re-fetches event data (for member-specific pricing).
seva:signed-outClears auth state and re-fetches event data.
seva:checkout-completeRe-fetches event data to show the registered state.
seva:event-selectedChanges to a different event by slug (useful with <seva-event-picker>).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Event Registration</title>
<script type="module" src="YOUR_COMPONENTS_URL/seva-auth.js"></script>
<script type="module" src="YOUR_COMPONENTS_URL/seva-event-register.js"></script>
<script type="module" src="YOUR_COMPONENTS_URL/seva-cart.js"></script>
<style>
body { font-family: system-ui, sans-serif; max-width: 480px; margin: 2rem auto; padding: 0 1rem; }
</style>
</head>
<body>
<seva-auth id="auth"
tenant-slug="my-club"
api-url="https://api.seva.tools">
</seva-auth>
<hr>
<seva-event-register id="register"
tenant-slug="my-club"
event-slug="annual-gala"
api-url="https://api.seva.tools">
</seva-event-register>
<hr>
<seva-cart id="cart"
tenant-slug="my-club"
api-url="https://api.seva.tools">
</seva-cart>
<script>
const auth = document.getElementById('auth');
const register = document.getElementById('register');
const cart = document.getElementById('cart');
function propagateAuth() {
const token = auth.getToken();
if (token) {
register.setAttribute('auth-token', token);
cart.setAttribute('auth-token', token);
} else {
register.removeAttribute('auth-token');
cart.removeAttribute('auth-token');
}
}
auth.addEventListener('seva:authenticated', propagateAuth);
auth.addEventListener('seva:signed-out', propagateAuth);
</script>
</body>
</html>