The embed code
In the form's שיתוף tab, הטמעת הטופס gives you the code to copy. For a form at formy.co.il/forms/service-agreement it is:

<iframe style="border:none;width:100%;" id="service-agreement" src="https://formy.co.il/forms/service-agreement"></iframe><script src="https://formy.co.il/widgets/formy-sdk.min.js"></script>- The iframe's
idis the form's slug. The SDK finds every iframe on the page whose address contains/forms/, so a second form needs only its own iframe. - A form in the ממוקד style, one question at a time, gets a fixed height of 700 pixels, at most 90% of the window, instead of growing with its content.
- Add prefill parameters to the iframe's
srcto open it with answers filled in. - Self-hosted installs with the SDK switched off hand out the older
https://formy.co.il/widgets/iframe.min.jswithinitEmbed()instead;initEmbedstill works with the SDK. - The popup embed ("as a popup" in the same section) is a different snippet with its own script and is not covered by this page.
Events
Listen to every form on the page with formy.on(event, handler), or to one with formy.get(idOrSlug).on(...). once listens a single time, off removes a handler, and on also takes an array of event names. Every payload carries form: { slug, id } as well as the fields below.
<script>
// Every embedded form on the page:
formy.on('ready', ({ form, currentPage }) => {
console.log('ready', form.slug, 'page', currentPage.index + 1, 'of', currentPage.total)
})
// One form, by its iframe id or slug:
const form = formy.get('service-agreement')
form.on('submitError', ({ errors }) => console.warn(errors))
let sent = false
form.on('submit', ({ data }) => {
if (sent) return // see "submit fires twice" below
sent = true
window.dataLayer?.push({ event: 'formy_submit', form: 'service-agreement' })
})
</script>| Event | When | Payload |
|---|---|---|
ready | The form has loaded. | slug, id, data, currentPage: { index, total }, darkMode |
dataChange | An answer changed. | data, changedField, previousValue, newValue |
pageChange | The respondent moved between pages. | fromPage, toPage, currentPage, totalPages (pages count from 0) |
nextPage, previousPage | The same move, by direction. | currentPage, totalPages |
error | The form shows validation errors. | errors, keyed by field ID |
submitStart | The respondent pressed submit. | nothing more |
submit | Formy accepted the response. | data, and completionTime (seconds) or submissionId when known: see below |
submitError | Formy refused the response. | errors, keyed by field ID, or { general } |
reset | The form was cleared to start again. | nothing more |
submit fires twice
On formy.co.il one submission currently emits submit twice. The first relays the message every embedded form posts to its parent page: its form.id is the form's number, and it carries completionTime, the seconds the respondent spent. The second comes through the SDK channel: its form.id is the iframe's id, and it carries submissionId when the form returns one. Guard your handler, as the example above does, so a conversion is counted once.
submissionId is the response's public ID, and it is present only when the form saves a response before answering (forms that let respondents edit their response, for example). Do not build on it as a key; for a record of every response, use a webhook.
Methods
const form = formy.get('service-agreement')
await form.setField('3f6c2a1e-8b4d-4c2f-9a71-1d2e3f4a5b6c', 'Dana Cohen')
await form.setFields({
'7b1e9c40-2d3a-4f5b-8c6d-0e1f2a3b4c5d': 'dana@example.com',
'8a1d4e2b-5c3f-4a6e-b7d8-9e0f1a2b3c4d': 'Package 2',
})
form.getData() // the answers as last reported by the form
await form.nextPage()
await form.submit()| Method | What it does |
|---|---|
setField(id, value), setFields({ id: value }) | Fill answers, by field ID. Values follow the prefill formats. |
clearField(id), clearAll() | Empty one answer, or all of them. |
getData(), getField(id) | The answers as the form last reported them (synchronous). |
getErrors(), getError(id), hasError(id) | The validation errors last reported. |
isFieldVisible(id) | Resolves to { visible }, after conditional logic. |
nextPage(), previousPage(), goToPage(index) | Move between pages. |
getCurrentPage(), canGoNext(), canGoPrevious() | Where the respondent is (synchronous). |
submit(), reset(), focusFirstError() | Submit, start again, or scroll to the first error. |
setDarkMode(true | false | 'auto'), toggleDarkMode(), isDarkMode() | Switch the form's colour scheme. |
isReady() | Whether ready has arrived. |
Commands return promises. A command waits for the handshake (up to 3 seconds after the frame loads) and then for the form to answer (up to 5 seconds), and rejects with an error after either. setTheme exists but is not implemented, and its promise rejects.
Call formy.init({ autoResize, preventRedirect, onReady }) to change the defaults: autoResize: false stops the frame from growing with its content, preventRedirect: true stops the SDK from sending the whole page to the form's after-submission address, and onReady(forms) runs once every form on the page is ready.
Security: the handshake and the origin lock
- For each iframe it finds, the SDK sends a handshake with a random token. The form answers only that token, and only to the page that framed it, and it locks onto that page's origin from then on.
- The SDK accepts events only from its own iframe's window and origin, so another frame on the page cannot fake a
submit. - Commands such as
setFieldcarry the token. The form refuses a command without it. - After a submission, the SDK follows the form's after-submission address only if it is an
httporhttpsURL, so a form owner cannot run script on your page. - Only the public form page,
formy.co.il/forms/<slug>, can be framed by any site. The dashboard and the editor sendframe-ancestorsthat allow only Formy itself and approved partners.
Campaign parameters from your page
During the handshake the SDK passes the campaign parameters of your page's own URL to the form: the 16 UTM and click-ID parameters Formy records (utm_source, gclid, fbclid and the rest). So a visitor who reached your landing page from an ad is attributed to that ad, although the form is in a frame, and the webhook payload carries them as attribution.
What an embedded form cannot do
- Use the camera. The embed code has no
allow="camera", so the barcode scanner field does not work in an embed. Link to the form instead. - Load your GA4, Meta Pixel or GTM. Conversion tracking never runs inside an embed; measure from your own page with the SDK's events.
- Create the iframe for you on another site.
formy.create()builds the frame with a relative address, so it only works on Formy's own pages. Paste the iframe yourself. - Reach the API. The SDK never sees your token and cannot read other responses.
Embedding the form editor
The editor itself can be embedded in a partner's product, such as a CMS, only for partners Formy has approved: other sites are refused by the editor's frame-ancestors. An approved embed posts formSaved, formDeleted and navigateBack events to the parent page, in messages of type opnform:editor:event, and the iframe address can pin them to the parent with _sdkParentOrigin. To ask about partner access, write to support@formy.co.il.
Questions developers ask
How do I know when someone submitted an embedded Formy form?
Listen for the submit event: formy.on('submit', handler). It fires when Formy accepts the response, with the answers in data. It currently fires twice for one submission, so guard the handler. For a server-side record of every response, add a webhook as well.
Can I prefill an embedded form from my page?
Yes, in two ways: put prefill parameters in the iframe's src, or call setField or setFields after the ready event. Both take field IDs, which the form's integrations tab lists under "אוטומציה ו-API".
Does the SDK need jQuery or a build step?
No. It is one script of about 11 KB compressed, served from formy.co.il, with no dependencies. Load it after the iframe; it finds the form by itself.
Can I embed a Formy form in WordPress, Wix or another site builder?
Yes, wherever you can paste HTML: an HTML or embed block takes the iframe and the script. Some builders strip script tags; the iframe alone still shows the form, without auto-resizing or the SDK.
Related
- Prefill and field IDs: Open the embed with answers filled in.
- Webhooks: A server-side record of every response.
- Embedded forms: The embed from the respondent's side, without code.
Every page of the docs is listed in Formy developer docs .
Try it on a free account
Every plan includes the API, webhooks, the embed SDK and the MCP server, Free included.
Create a free account