Appearance
Embedding & Messaging
A host application never imports the engine; it loads the engine's index.html in an iframe and exchanges messages with it. This keeps the engine isolated from the host page and lets the same bundle run in the admin web app, the patient mobile app, the designer preview and on public web pages.
Who embeds engines
| Host | When |
|---|---|
| Admin web app | Designer preview (live, section- or question-scoped), answering on behalf of a patient, schedule preview |
| Patient mobile app | Every scheduled questionnaire; the engine files are stored on the device and load without connectivity |
| Anonymous questionnaire wrapper | Public links: the engine and a wrapper are combined into one page that submits without a host |
| Your application | Any page that can render an iframe and post messages |
The protocol
Messages are plain objects with a type and, where relevant, a payload. The host must send serialisable data (no live framework objects).
Host → engine
| Type | When | Contents |
|---|---|---|
init | After the iframe has loaded | questionnaire: the published definition. config: the runtime options (sections to show, questionnaire and interface language, optional scoring override, colour mode, zoom, and the engine options stored with the questionnaire). |
A minimal initialisation:
js
frame.contentWindow.postMessage(
{
type: "init",
questionnaire, // published questionnaire definition
config: {
sections: ["<section id>"],
questionnaire_preferred_language: "en_GB",
user_preferred_language: "en_GB",
colorMode: "auto",
},
},
"*",
);Engine → host
| Type | When | Payload |
|---|---|---|
submit | The questionnaire is complete or ended by logic | answers keyed by question identifier, each with question, answer and errors; plus the final scoring state |
exit | The patient asks to leave | none; the host decides whether to confirm and how to close |
haptics | A component requests device feedback | The effect name (impact, selection, success, warning, error) |
error | A runtime problem that the engine recovered from | code, message and the affected question, for logging or a non-blocking notice |
The engine sends submit once. Hosts should ignore any message after they have accepted a submission, to avoid duplicate processing during close animations.
What the host must provide
- The engine location: the questionnaire definition carries the engine identity and base URL, so a host resolves
index.htmlfrom it. The mobile app substitutes a local copy. - The section selection: for scheduled questionnaires, the sections due at this point in the schedule; for a full run, all sections.
- Language preferences for the patient.
- A submission path: the host is responsible for sending the submission to the Medipal API with the right context (patient, enrollment, schedule slot, source).
- A viewport: engines lay out for a phone-sized viewport. The web app renders them inside a phone frame scaled to the available space; the mobile app gives them the full screen.
Sandboxing and safety
- Load the iframe with the
sandboxattribute allowing scripts only. The engine needs nothing else. - Accept messages only from the frame you created and only for the types listed above.
- Treat
submitpayloads as untrusted input; the Medipal API validates submissions server-side. - Do not pass secrets or session material into
init; the engine does not need them and the bundle is a static file.
Anonymous questionnaires
For public questionnaires no host application is needed. The anonymous questionnaire wrapper combines an engine bundle, a questionnaire definition and a submission configuration into a single static page. When opened, the page:
- shows the questionnaire's legal documents as a consent gate first, if any are enabled, and records which documents were displayed and accepted;
- initialises the embedded engine itself;
- intercepts the engine's submission and sends it to the anonymous submission endpoint of the instance;
- shows a completion or error overlay.
Optional start and end dates make the page show an availability notice outside the window. Links are generated from the questionnaire's enrollments page; see Anonymous Questionnaires. The generated page can be hosted on any static site or embedded in your own site in an iframe.