Handle form events

Makeform embed events let you track form readiness, submissions, and popup or slider opening and closing for free on every plan. Get your form embed from Share > Embed Form, then enable events in your website code.

Makeform is a free AI form builder: describe what you want to collect and it builds the form for you, with unlimited forms and submissions on the free plan.


Event layers

Makeform uses two event layers:

Layer Who uses it How to listen
SDK CustomEvents Most website analytics and app code window.addEventListener('MakeForm:submit', handler)
iframe postMessage Advanced integrations and debugging window.addEventListener('message', handler)

For most websites, use SDK CustomEvents. The SDK validates the iframe source and converts Makeform iframe messages into simpler MakeForm:* events when you opt in.


Enable events

Standard embed

Add data-makeform-events to the iframe:

HTML
<iframe
  data-makeform-src="https://www.makeform.ai/e/YOUR_FORM_ID"
  data-makeform-auto-resize
  data-makeform-events
  loading="lazy"
  style="width: 100%; height: 200px; border: 0;"
  title="Makeform form"
></iframe>
<script async src="https://www.makeform.ai/widgets/embed.js"></script>

Standard embeds dispatch MakeForm:ready and MakeForm:submit.

For data-attribute triggers, add data-makeform-events to the trigger:

HTML
<button
  data-makeform-popup="https://www.makeform.ai/e/YOUR_FORM_ID"
  data-makeform-events
>
  Open Form
</button>
<script async src="https://www.makeform.ai/widgets/embed.js"></script>

For the JavaScript API, set dispatchEvents: true:

JavaScript
MakeForm.openPopup("YOUR_FORM_ID", {
  dispatchEvents: true
});

Popup and slider embeds can dispatch MakeForm:open, MakeForm:ready, MakeForm:submit, and MakeForm:close.

Full page embed

Full page embeds use /f/{FORM_ID}. To emit submission events, append __mf_emitEvents=1, use data-makeform-src, and add data-makeform-events:

HTML
<iframe
  data-makeform-src="https://www.makeform.ai/f/YOUR_FORM_ID?__mf_emitEvents=1"
  data-makeform-events
  style="position: absolute; inset: 0; border: 0; width: 100%; height: 100%;"
  title="Makeform form"
></iframe>
<script async src="https://www.makeform.ai/widgets/embed.js"></script>

SDK CustomEvents

MakeForm:ready

Fires when the form iframe reports that it has loaded.

JavaScript
window.addEventListener("MakeForm:ready", (event) => {
  console.log("Ready:", event.detail.formId);
});

MakeForm:submit

Fires when the form is successfully submitted.

JavaScript
window.addEventListener("MakeForm:submit", (event) => {
  console.log("Submitted form:", event.detail.formId);
  console.log("Submission data:", event.detail.data);
});

MakeForm:open

Fires when a popup or slider opens.

JavaScript
window.addEventListener("MakeForm:open", (event) => {
  console.log("Opened:", event.detail.formId);
});

MakeForm:close

Fires when a popup or slider closes.

JavaScript
window.addEventListener("MakeForm:close", (event) => {
  console.log("Closed:", event.detail.formId);
});

PostMessage events

The form iframe sends postMessage payloads to its parent window. These are useful if you are building a custom wrapper around the embed SDK.

MakeForm.Loaded

JSON
{
  "type": "MakeForm.Loaded",
  "payload": {}
}

MakeForm.SubmitSuccess

JSON
{
  "type": "MakeForm.SubmitSuccess",
  "payload": {
    "Name": "Jane Doe",
    "Email": "jane@example.com"
  }
}

Internal layout messages

The SDK also listens for these iframe messages:

Event Purpose
MakeForm.SetHeight Auto-resizes standard embeds and popup height. Payload shape: { "height": 640 }.
MakeForm.LayoutReady Reveals popups only after the first stable layout height is available.
MakeForm.SetBackgroundColor Syncs modal background color with the form background.
MakeForm.Submitted Payload-free submit signal used for safe auto-close on /f popup embeds.

Complete examples

window.addEventListener("MakeForm:ready", (event) => {
  console.log("Form ready:", event.detail.formId);
});

window.addEventListener("MakeForm:submit", (event) => {
  console.log("Submitted:", event.detail.formId, event.detail.data);
});

window.addEventListener("MakeForm:open", (event) => {
  console.log("Modal opened:", event.detail.formId);
});

window.addEventListener("MakeForm:close", (event) => {
  console.log("Modal closed:", event.detail.formId);
});
type MakeFormEventDetail = {
  formId: string;
  data?: Record<string, unknown>;
};

const onSubmit = (event: Event) => {
  const detail = (event as CustomEvent<MakeFormEventDetail>).detail;
  console.log("Submitted:", detail.formId, detail.data);
};

window.addEventListener("MakeForm:submit", onSubmit);
'use client';

import Script from 'next/script';
import { useEffect } from 'react';

export function EmbeddedForm({ formId }: { formId: string }) {
  useEffect(() => {
    const handleSubmit = (event: Event) => {
      const detail = (event as CustomEvent).detail;
      console.log('Submitted:', detail.formId, detail.data);
    };

    window.addEventListener('MakeForm:submit', handleSubmit);
    return () => window.removeEventListener('MakeForm:submit', handleSubmit);
  }, []);

  return (
    <>
      <iframe
        data-makeform-src={`https://www.makeform.ai/e/${formId}`}
        data-makeform-auto-resize
        data-makeform-events
        loading="lazy"
        style={{ width: '100%', height: 200, border: 0 }}
        title="Makeform form"
      />
      <Script
        async
        src="https://www.makeform.ai/widgets/embed.js"
        onLoad={() => window.MakeForm?.loadEmbeds?.()}
      />
    </>
  );
}

Advanced postMessage listener

If you listen to raw iframe messages, validate the origin before using the payload:

JavaScript
window.addEventListener("message", (event) => {
  if (
    event.origin !== "https://www.makeform.ai" &&
    event.origin !== "https://makeform.ai"
  ) {
    return;
  }

  if (typeof event.data !== "string") return;

  try {
    const data = JSON.parse(event.data);

    if (data.type === "MakeForm.SubmitSuccess") {
      console.log("Submission:", data.payload);
    }
  } catch {
    // Ignore unrelated postMessage traffic.
  }
});

Event reference

SDK CustomEvents

Event Fires when Detail
MakeForm:ready Form iframe reports loaded { formId }
MakeForm:submit Form submission succeeds { formId, data }
MakeForm:open Popup or slider opens { formId }
MakeForm:close Popup or slider closes { formId }

iframe postMessage events

Event Public use
MakeForm.Loaded Advanced wrapper can detect iframe readiness
MakeForm.SubmitSuccess Advanced wrapper can read submission data
MakeForm.SetHeight Internal resizing
MakeForm.LayoutReady Internal popup reveal timing
MakeForm.SetBackgroundColor Internal modal background sync
MakeForm.Submitted Internal payload-free auto-close signal

Best practices

  1. Use SDK CustomEvents first They are easier to consume and work across standard, popup, and slider embeds when event tracking is enabled.

  2. Clean up listeners in SPAs Remove event listeners when components unmount.

  3. Validate postMessage origin Raw message listeners receive traffic from many sources. Check event.origin before reading the payload.

  4. Do not build product logic on layout messages SetHeight, LayoutReady, SetBackgroundColor, and Submitted exist for SDK behavior and can change as the embed runtime evolves.