Install Eventual RSVP – Core, Registrations, and Tickets on EmDash.

Choose between Registry, sandboxed npm, or native npm installation depending on your host, then add the capacity field pack and required Astro visitor routes.

  • Available
  • EmDash ≥ 1.2.0 < 2.0.0 (1.4.0 recommended)
  • Cloudflare Workers Paid · Node 24+
Eventual RSVP – Core settings in EmDash admin: choice of the content types used for events, venues and organisers.Eventual RSVP – Core settings in EmDash admin: choice of the content types used for events, venues and organisers.

Host runtime & plan

EmDash >=1.2.0 <2.0.0 (1.4.0 recommended). Sandboxed deployment on Cloudflare requires Workers Paid for the LOADER worker_loaders binding, re-exported PluginBridge, and EMDASH_SITE_URL.

Email plugin required

Configure an EmDash email provider plugin for confirmations, 2-hour waitlist offers, reminders, bank invoice emails, and ticket QR links.

Encryption key (cards only)

Only needed for pasted Stripe secret keys in Tickets. Core, Registrations, free tickets, invoices, Turnstile, and offline evt1.… keys work without it.

Three supported ways to install

Eventual RSVP – Core 0.18.2, Eventual RSVP – Registrations 0.1.1 and Eventual RSVP – Tickets 0.1.3 are on the EmDash Registry and on npm.

Open EmDash Admin → Plugins → Registry, inspect the declared capabilities, and install the plugin published by vermeulen.solutions. Note that standalone Astro UI components (.astro) are still imported from the corresponding npm package.

Recommended setup: runs each plugin in an isolated Worker sandbox bounded to explicit permissions and the 10-call host budget.

// astro.config.mjs
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import eventual from "@vermeulen.solutions/eventual"; // Eventual RSVP – Core
import eventualAttendance from "@vermeulen.solutions/eventual-attendance";
import eventualTickets from "@vermeulen.solutions/eventual-tickets";

export default defineConfig({
  integrations: [
    emdash({
      // database, storage, email provider…
      sandboxed: [eventual, eventualAttendance, eventualTickets],
      sandboxRunner: "@emdash-cms/cloudflare/sandbox", // on Node: "@emdash-cms/sandbox-workerd/sandbox"
    }),
  ],
});

On Cloudflare Workers Paid, add the Worker Loader binding in wrangler.jsonc and re-export PluginBridge from your Worker entrypoint:

// wrangler.jsonc
{
  "worker_loaders": [{ "binding": "LOADER" }]
}

// src/worker.ts (your main Worker entry)
export { PluginBridge } from "@emdash-cms/cloudflare/worker";

If enabling Stripe card checkout in Tickets, create EMDASH_ENCRYPTION_KEY with npx emdash secrets generate and store it via wrangler secret put EMDASH_ENCRYPTION_KEY.

Use only on trusted self-hosted Node environments where you control all code: runs plugins directly in the site process without sandbox isolation.

// astro.config.mjs (Node hosts you trust only)
import { defineConfig } from "astro/config";
import emdash from "emdash/astro";
import eventual from "@vermeulen.solutions/eventual"; // Eventual RSVP – Core
import eventualAttendance from "@vermeulen.solutions/eventual-attendance";
import eventualTickets from "@vermeulen.solutions/eventual-tickets";

export default defineConfig({
  integrations: [
    emdash({
      // database, storage, email provider…
      plugins: [eventualAttendance, eventualTickets],
      // Core always runs sandboxed, also on Node.
      sandboxed: [eventual],
      sandboxRunner: "@emdash-cms/sandbox-workerd/sandbox",
    }),
  ],
});

Capacity field pack and required Astro pages

Core owns events, venues, and organisers. Registrations and Tickets coordinate per-event ownership through three additive schema fields, then render on dedicated visitor and door-staff pages.

  1. Export collections & merge shared capacity fields

    Export Core’s native schema (with its npm package), merge the @vermeulen.solutions/eventual-capacity fields, review the JSON diff, and seed or migrate your collections:

    npx -p @vermeulen.solutions/eventual eventual-schema --locale fr --output eventual-schema.json
    npx -p @vermeulen.solutions/eventual-capacity eventual-capacity-fields --merge eventual-schema.json --output eventual-schema-with-capacity.json

    Important handoff contract: recurring Core feed items have id "<contentId>#<recurrenceId>". Always pass eventId={event.id.split("#")[0]} and occurrenceStart={event.start}.

  2. Add event form & /rsvp/manage page (Eventual RSVP – Registrations)

    Place <RsvpForm /> on event pages and create the required self-service page at /rsvp/manage (matching Site setup in Registrations settings):

    // src/pages/rsvp/manage.astro
    import RsvpManage from "@vermeulen.solutions/eventual-attendance/astro/RsvpManage.astro";
    <RsvpManage locale="en" />
    
    // On an event detail page:
    import RsvpForm from "@vermeulen.solutions/eventual-attendance/astro/RsvpForm.astro";
    <RsvpForm eventId={contentId} occurrenceStart={event.start} locale="en" />
  3. Add /tickets/checkout, /tickets/order & /tickets/check (Eventual RSVP – Tickets)

    For Eventual RSVP – Tickets, add <TicketCheckout /> on event pages plus return, buyer order, and authenticated staff door-check routes:

    // Event page:
    import TicketCheckout from "@vermeulen.solutions/eventual-tickets/astro/TicketCheckout.astro";
    <TicketCheckout eventId={contentId} occurrenceStart={event.start} locale="en" />
    
    // /tickets/checkout -> <TicketCheckoutReturn backHref="/events" locale="en" />
    // /tickets/order    -> <TicketOrder checkinPath="/tickets/check" locale="en" />
    // /tickets/check    -> <TicketCheckin locale="en" /> (keep behind authenticated staff access)