postMessage protocol. The @feedal/content-type-sdk package provides a minimal bridge so you don’t have to implement the protocol yourself.
Security model
Community plugin UI never runs in the Feedal origin. Your bundle is loaded in an iframe withsandbox="allow-scripts" only:
- No access to the parent page’s DOM, localStorage, or cookies
- No cross-origin network requests from the iframe (except to your own CDN for the bundle itself)
postMessageis the only communication channel between your plugin and Feedal
How it works
Installing the SDK
SDK reference
onRender(callback)
Registers a callback that fires every time Feedal sends a PLUGIN_RENDER message. Returns an unsubscribe function.
The RenderPayload passed to the callback:
sendAnswer(value)
Sends the respondent’s answer to the host page. Call this when the user makes a selection or submits input. value can be any JSON-serialisable type.
signalReady()
Signals to the host page that your iframe has finished loading and is ready to receive PLUGIN_RENDER messages. Call this once, after your bundle is initialised.
sendSize(height)
Requests the host page to resize the iframe to height pixels. Call this whenever your content changes height to avoid scroll bars or clipped content.
Raw postMessage protocol
If you’re not using the SDK, here are the raw message types: Host → iframe
iframe → host
Building your bundle
Your renderer must be a self-contained ES module bundle served over HTTPS. Therenderer_bundle_url in your manifest must point to this file.
<script type="module">. There is no HTML shell — your bundle is responsible for creating DOM elements and appending them to document.body.
Minimal example
Validation
What the framework handles
Feedal enforces one rule on behalf of every question type, including plugins: required fields. Ifnode.data.is_required is true and the respondent hasn’t submitted an answer yet, the runner blocks navigation and shows “This field is required.” before your plugin ever receives a PLUGIN_RENDER event for the next node.
That’s the only validation the framework performs for plugins. Everything else is your responsibility.
What your plugin handles
All content-level validation — format checks, range limits, minimum selections, custom business rules — must be enforced inside the iframe. The pattern is:- Show the input and let the respondent interact.
- When input is invalid, display an inline error message inside the iframe and do not call
sendAnswer(). - Only call
sendAnswer(value)once the value is valid.
PLUGIN_ANSWER message, withholding sendAnswer() is the complete and correct way to block navigation. There is no separate validation API.
The needsContinueButton manifest field
By default, plugins behave like choice or rating questions: the runner expects sendAnswer() to be called on a single user action and does not render an explicit Continue button.
If your plugin has a multi-step input or needs the respondent to explicitly confirm before advancing (for example, a signature pad or a file picker with a preview step), set needs_continue_button: true in your manifest:
needs_continue_button is true, Feedal renders a themed Continue button below your iframe — the same button used for text input questions. The respondent clicks it to advance; your plugin should already have called sendAnswer() with the current value before that click.
If needs_continue_button is false (the default), no Continue button is rendered. Your plugin should call sendAnswer() as the final confirmation action.
answerSchema
The answerSchema field in the manifest is informational only. It documents the shape of the value you pass to sendAnswer() and is used for type hints in the developer portal and the Results Hub. Feedal does not validate answer values against this schema at runtime.
Registering with the manifest
Add acontent_type extension point to your app manifest:
question_type_id becomes available in the studio’s Add content panel and in the form graph as "question_type": "plugin:signature-capture".
Testing locally
During development, simulate the postMessage protocol in a plain HTML file to test your bundle without a live Feedal account:src to a local server that serves your bundle.
Next steps
Developer portal
Submit your plugin for marketplace review.
Marketplace
Browse community and official plugins.