<seva-event-register-cta>
The <seva-event-register-cta> component is the on-page anchor for registration state on a Webflow event page. It renders a single CTA whose label and behavior reflect the current user’s relationship to the event: not registered, registered, or declined.
Overview
Section titled “Overview”This is the recommended entry point for embedding registration on a Webflow event detail page that already shows event information itself. Instead of duplicating the event header / dates / description, the CTA renders just the action surface:
| State | What renders |
|---|---|
| Pre-registration | A “Register” button (or “Continue Registration” if a cart item already exists for this event), an optional late-fee notice, and — if signed in — a “Decline” button. |
| Registered | A summary card via <seva-event-registration-status> with attendees, ticket details, and Add Guests / Cancel actions. |
| Declined | A “You’ve declined this event” message with a “Register Instead” affordance. |
This is an inline component — it reads the auth token from localStorage (written by <seva-auth> or any modal component). It does not own any auth UI itself. The user signs in inside the <seva-event-register-modal> that the CTA opens.
The CTA does not display event details (title, dates, location) — your page is expected to render those. If you want the form to render its own event header, use <seva-event-register> directly instead.
Quick Example
Section titled “Quick Example”<script type="module" src="YOUR_COMPONENTS_URL/seva-event-register-cta.js"></script><script type="module" src="YOUR_COMPONENTS_URL/seva-event-register-modal.js"></script>
<seva-event-register-cta event-slug="annual-gala" tenant-slug="my-club" api-url="https://api.seva.tools"></seva-event-register-cta>
<!-- Modal must also be on the page; CTA opens it via seva:open-registration. --><seva-event-register-modal tenant-slug="my-club" api-url="https://api.seva.tools"></seva-event-register-modal>The CTA dispatches seva:open-registration on document when the user clicks Register; the modal listens for that event and opens itself. Both components must be present on the same page for the flow to work.
Attributes
Section titled “Attributes”| Attribute | Type | Default | Description |
|---|---|---|---|
event-slug | string | '' | Required. Slug of the event to display registration state for. Updating this attribute triggers a re-fetch. |
tenant-slug | string | '' | Required. Your organization’s tenant slug; scopes API calls and localStorage keys. |
api-url | string | 'https://api.seva.tools' | Base URL of the Seva API. |
theme | 'light' | 'dark' | 'light' | Color theme. |
Events emitted
Section titled “Events emitted”All events are dispatched on document and bubble through the Shadow DOM.
| Event | Detail | When it fires |
|---|---|---|
seva:open-registration | { eventSlug, view? } | User clicks the primary “Register” / “Continue Registration” button, or chooses “Add Guests” from the registered-state card (in which case view: 'guest-info' is included). The modal listens for this event. |
seva:registration-canceled | { eventSlug } | After the cancel-registration API call returns. Other CTAs and the modal listen for this. |
seva:registration-declined | { eventSlug } | After the user clicks “Decline” and the API call returns. |
The CTA also dispatches seva:open-my-registrations (no payload) when an authenticated user clicks the “View All My Registrations” link beneath the action buttons — to be picked up by an <seva-my-registrations> element if one is on the page.
Events listened for
Section titled “Events listened for”The CTA subscribes to seven document-level events to keep its rendered state in sync with auth, cart, and registration changes:
| Event | Effect |
|---|---|
seva:authenticated | Stores the user/token and re-fetches event + registration state. |
seva:signed-out | Clears the user/token and re-fetches state (becomes anonymous view). |
seva:registration-completed | Re-fetches; transitions to the “registered” view. |
seva:registration-canceled | Re-fetches; returns to the “pre-registration” view. |
seva:registration-declined | Re-fetches; transitions to the “declined” view. |
seva:cart-updated | Reloads the cart store; updates button label between “Register” and “Continue Registration”. |
seva:add-to-cart | Same as seva:cart-updated. |
seva:checkout-complete | Re-fetches the registration — this is the authoritative happy-path signal that a cart item became a real registration. |
Behavior notes
Section titled “Behavior notes”- Renders nothing in three cases: the event slug returns 404 from the API, the event has already ended, or the initial load is in flight. The 404 branch is silent by design (no error UI on the page) so a typo’d
event-slugproduces an empty space rather than a visible error. A console-warn breadcrumb for misconfigured slugs is tracked inTODOS.md(entry #136). - Late-fee notice is shown automatically if the event has a configured late fee. The wording adapts based on whether the deadline has passed and whether the late fee applies to the registrant, guests, both, or a mixed catalog.
- Decline button is shown only when the user is authenticated and
event.showDeclineButton !== false. The label can be customized via the event’sdeclineButtonLabel. - The CTA never renders the registration form itself. All sign-in, attendee selection, and ticket choice happens inside the modal it opens.
Cross-component coordination
Section titled “Cross-component coordination”The CTA is one piece of a small ecosystem:
<seva-event-register-modal>— required. The CTA opens it viaseva:open-registration; the modal contains the actual registration form.<seva-event-register>— the underlying form, embedded inside the modal. You usually do not place this on the page directly when using the CTA pattern.<seva-cart>/<seva-cart-drawer>— the CTA flips its label to “Continue Registration” when the cart already contains an item for this event.<seva-event-registration-status>— internal sub-component that renders the post-registration card. You don’t embed it directly; the CTA does so when in the “registered” view.
Full Example
Section titled “Full Example”A Webflow event detail page with the CTA, modal, cart, and cart drawer wired together:
<!DOCTYPE html><html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Annual Gala — My Club</title> <script type="module" src="YOUR_COMPONENTS_URL/seva-event-register-cta.js" ></script> <script type="module" src="YOUR_COMPONENTS_URL/seva-event-register-modal.js" ></script> <script type="module" src="YOUR_COMPONENTS_URL/seva-cart.js"></script> <script type="module" src="YOUR_COMPONENTS_URL/seva-cart-drawer.js" ></script> </head> <body> <!-- Your Webflow event header / hero / description --> <h1>Annual Gala</h1> <p>Join us for the biggest fundraiser of the year…</p>
<!-- Registration anchor --> <seva-event-register-cta event-slug="annual-gala" tenant-slug="my-club" api-url="https://api.seva.tools" > </seva-event-register-cta>
<!-- Modal that the CTA opens (must be in the DOM) --> <seva-event-register-modal tenant-slug="my-club" api-url="https://api.seva.tools" > </seva-event-register-modal>
<!-- Cart icon (optional) and drawer for checkout --> <seva-cart tenant-slug="my-club" api-url="https://api.seva.tools"> </seva-cart> <seva-cart-drawer tenant-slug="my-club" api-url="https://api.seva.tools"> </seva-cart-drawer> </body></html>See Wiring components together for a diagram of how these elements coordinate via document events.