Embedding Forms
Embed Formalingo forms on any website using iframes or the JavaScript SDK.
Embedding Forms
Formalingo forms can be embedded on external websites using two methods: a simple iframe snippet or the JavaScript SDK with auto-resize and event callbacks.
Quick Start — iFrame
The simplest way to embed a public form:
<iframe
src="https://your-domain.com/f/public/PUBLIC_TOKEN"
width="100%"
height="600"
frameborder="0"
style="border: none;"
></iframe>Replace PUBLIC_TOKEN with your form's public token (found in the form editor Settings tab or the form detail page).
Quick Start — JavaScript SDK
For richer control including auto-resize and event callbacks, use the embed SDK:
<div id="my-form"></div>
<script src="https://your-domain.com/embed.js"></script>
<script>
Formalingo.createForm({
container: '#my-form',
formUrl: 'https://your-domain.com/f/public/PUBLIC_TOKEN',
onSubmit: function(data) {
console.log('Form submitted!', data);
},
onReady: function(data) {
console.log('Form loaded', data);
}
});
</script>The SDK automatically resizes the iframe to fit the form content, eliminating scrollbars.
SDK Options Reference
| Name | Type | Description |
|---|---|---|
| container | string | HTMLElement | CSS selector or DOM element where the form will be rendered. Required. |
| formUrl | string | Full form URL or public token. Required. |
| height | number | Initial iframe height in pixels. Default: 600. |
| autoResize | boolean | Auto-resize iframe based on form content height. Default: true. |
| onReady | function(payload) | Called when the form is fully loaded and interactive. |
| onSubmit | function(payload) | Called when the form is successfully submitted. |
| onRedirect | function(payload) | Called before a post-submission redirect. Return false to cancel the redirect. |
| onQuestionAnswered | function(payload) | Called when a question answer changes. |
| onError | function(payload) | Called when a form error occurs. |
| onHeightChange | function(payload) | Called when the form content height changes. |
The createForm method returns an object with:
iframe— the HTMLIFrameElement referencedestroy()— removes the iframe and cleans up event listeners (useful for SPAs)
postMessage Events
Embedded forms emit events to the parent window via postMessage. All events are prefixed with formalingo. and have this structure:
{
"type": "formalingo.eventName",
"payload": { ... }
}Event Reference
| Name | Type | Description |
|---|---|---|
| formalingo.formLoaded | { formId, title } | The form component has mounted. |
| formalingo.formReady | { formId, title, questionCount } | The form is fully loaded and interactive. |
| formalingo.questionAnswered | { formId, questionId, questionType, questionIndex, totalQuestions } | A question answer was changed. Does not include the answer value for privacy. |
| formalingo.formSubmitted | { formId, recipientId } | The form was successfully submitted. |
| formalingo.formHeight | { formId, height } | The document height changed (used for auto-resize). |
| formalingo.formRedirect | { formId, url } | A post-submission redirect is about to happen (embedded forms only). |
| formalingo.formError | { formId, error, code } | An error occurred during form interaction. |
Listening to Events Without the SDK
If you use the iframe embed directly (without the SDK), you can listen for events manually:
window.addEventListener('message', function(event) {
var data = event.data;
if (!data || !data.type || data.type.indexOf('formalingo.') !== 0) return;
switch (data.type) {
case 'formalingo.formSubmitted':
console.log('Form submitted:', data.payload);
break;
case 'formalingo.formHeight':
// Auto-resize the iframe
document.querySelector('iframe').style.height = data.payload.height + 'px';
break;
}
});Domain Whitelisting
Restrict which websites can embed your form for security. When enabled, browsers will block embedding from unlisted domains.
Via Dashboard
- Open the form editor Settings tab
- Scroll to the Embed section
- Toggle Domain Whitelisting on
- Add allowed domains (e.g.,
example.com,*.company.io)
Via API
curl -X PUT https://formalingo.com/api/v1/forms/FORM_ID/settings \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"embed_allowed_domains": ["example.com", "*.company.io"]
}'Set to null to disable whitelisting and allow embedding from any domain:
curl -X PUT https://formalingo.com/api/v1/forms/FORM_ID/settings \
-H "Authorization: Bearer af_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"embed_allowed_domains": null
}'Embedding Private Forms
Private forms (shared via individual recipient links) can also be embedded using the recipient token URL:
<iframe
src="https://your-domain.com/f/RECIPIENT_TOKEN"
width="100%"
height="600"
frameborder="0"
style="border: none;"
></iframe>Or with the SDK:
Formalingo.createForm({
container: '#my-form',
formUrl: 'https://your-domain.com/f/RECIPIENT_TOKEN'
});All postMessage events work identically for private forms. Password-protected forms will display the password gate inside the iframe.
Troubleshooting
| Issue | Cause | Fix |
|---|---|---|
| Form doesn't load in iframe | Domain blocked by whitelist | Check the form's embed_allowed_domains setting |
| No auto-resize | SDK script not loaded | Verify the embed.js script tag loads correctly |
| Redirect doesn't work when embedded | Embedded forms emit formRedirect instead of navigating | Use the onRedirect callback to handle redirects in the parent page |
Console error: Refused to display in a frame | CSP frame-ancestors restriction | Add your domain to the form's allowed embed domains |