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.
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.
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.jsonImportant handoff contract: recurring Core feed items have id "<contentId>#<recurrenceId>". Always pass eventId={event.id.split("#")[0]} and occurrenceStart={event.start}.
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" />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)

