EmDash CMS
EmDash is Cloudflare’s TypeScript CMS, built on Astro and running on Workers. It exists largely because plugins are the security problem with WordPress, so it sandboxes them in Worker isolates.
That makes it a good fit twice over.
In content: no plugin at all
Section titled “In content: no plugin at all”Paste the snippet into an HTML or embed block:
<div data-fb-form="YOUR-FORM-ID"></div><script src="https://forms.justinjongstra.nl/formbuilder/asset/embed.js" async></script>Nothing runs inside the CMS. There is no plugin to sandbox, nothing with database access, and nothing to keep patched. The form is fetched by the visitor’s browser from the form host.
Because EmDash is Astro, <formbuilder-form> also works directly in a
component or .mdx file, exactly as on the Astro page.
In the admin: a plugin that embeds the builder
Section titled “In the admin: a plugin that embeds the builder”If you would rather edit forms without leaving the CMS, EmDash plugins can contribute pages to the admin panel, and those pages run in a sandboxed iframe that talks to the admin app by message passing.
That is the same shape the builder already supports: it renders standalone
inside a frame, which is what ?embed=1 is for.
import { definePlugin } from 'emdash/plugin';
export default definePlugin({ id: 'formbuilder', name: 'FormBuilder', capabilities: ['admin-ui', 'settings'],
settings: { appUrl: { type: 'string', label: 'FormBuilder URL', default: 'https://forms.justinjongstra.nl' }, },
adminPages: [ { path: '/forms', label: 'Forms', // The panel is an iframe either way, so pointing it at the // builder is the whole integration. render: ({ settings }) => ({ type: 'iframe', src: `${settings.appUrl}/formbuilder?embed=1`, }), }, ],});- Drop the plugin in your EmDash project and enable it.
- Set the FormBuilder URL in its settings.
- Sign in to FormBuilder once in that browser. The panel shares the session, so the frame is already authenticated.
The panel needs your FormBuilder host to allow framing from your CMS
domain. Add it to the form’s allowed origins and the host sends a matching
frame-ancestors, which is what stops any other site putting your builder
in a frame.