DeveloperEmbed SDKDeveloper Resources

Developer Resources

Complete JavaScript API reference for programmatic control of MakeForm embedded forms, popups, and sliders.

🎁
The MakeForm embed SDK is available for free to all Makeform users.

Including the SDK

Add the embed script to your page:

<script async src="https://www.makeform.ai/widgets/embed.js"></script>

The script exposes the global MakeForm object. It can be placed in the <head> or before </body>. It initializes existing data-makeform-src, data-makeform-popup, data-makeform-slider, and auto-open configuration when the DOM is ready.


API methods

MakeForm.loadEmbeds()

Scans the DOM for elements with data-makeform-src and initializes them as embedded forms.

MakeForm.loadEmbeds();

Call this after dynamically adding embed elements to the page (e.g., after SPA navigation).

MakeForm.loadPopups()

Scans for elements with data-makeform-popup and attaches click handlers.

MakeForm.loadPopups();

MakeForm.loadSliders()

Scans for elements with data-makeform-slider and attaches click handlers.

MakeForm.loadSliders();

MakeForm.loadAutoOpen()

Processes window.MakeFormConfig and window.MakeFormConfigs to set up auto-open triggers.

MakeForm.loadAutoOpen();

MakeForm.openPopup(formId, options?)

Opens a popup modal programmatically.

MakeForm.openPopup("YOUR_FORM_ID", {
  width: 500,
  position: "bottom-right",
  overlay: false,
  initialBgColor: "#ffffff",
  hiddenFields: { user_id: "123" },
  dispatchEvents: true,
  autoCloseMs: 3000,
  onOpen: ({ formId }) => console.log("Opened:", formId),
  onReady: ({ formId }) => console.log("Ready:", formId),
  onSubmit: ({ formId, data }) => console.log("Submitted:", data),
  onClose: ({ formId }) => console.log("Closed:", formId)
});

MakeForm.closePopup()

Closes the currently open popup.

MakeForm.closePopup();

MakeForm.openSlider(formId, options?)

Opens a slider panel programmatically. Accepts the same options as openPopup, plus a position option for slider side.

MakeForm.openSlider("YOUR_FORM_ID", {
  width: 400,
  position: "left",
  onSubmit: ({ formId, data }) => {
    console.log("Feedback received:", data);
  }
});

MakeForm.closeSlider()

Closes the currently open slider.

MakeForm.closeSlider();

MakeForm.registerAutoOpen(config)

Registers a single auto-open configuration at runtime. Useful for dynamically adding forms after the SDK has loaded.

MakeForm.registerAutoOpen({
  formId: "YOUR_FORM_ID",
  popup: {
    width: 500,
    open: { trigger: "time", ms: 5000 }
  }
});

ModalOptions

Options object for openPopup() and openSlider():

interface ModalOptions {
  type?: 'embed' | 'form';       // 'embed' uses /e/ route, 'form' uses /f/ route
  embedUrl?: string;              // Pre-built embed URL; preserves its origin
  hiddenFields?: Record<string, string | number | boolean | null>;
  width?: number;                 // Modal width in px (360–800)
  position?: string;              // Popup: 'center' | 'bottom-right'; Slider: 'left' | 'right'
  overlay?: boolean;              // Show dark backdrop (popup only)
  initialBgColor?: string;        // CSS color to prevent white flash
  onOpen?: (payload: { formId: string }) => void;
  onReady?: (payload: { formId: string }) => void;
  onSubmit?: (payload: { formId: string; data: Record<string, any> }) => void;
  onClose?: (payload: { formId: string }) => void;
  dispatchEvents?: boolean;       // Dispatch CustomEvents on window
  autoCloseMs?: number | null;    // Auto-close delay in ms (0–30000)
}
OptionTypeDescriptionDefault
type'embed' | 'form'Route type: embed = /e/, form = /f/'embed'
embedUrlstringPre-built embed URL. Useful when you need to preserve a generated URL or custom origin
hiddenFieldsobjectKey-value pairs passed as URL parameters
widthnumberModal width in pixels, clamped to 360–800Popup CSS default, slider 500
positionstringPopup: 'center' or 'bottom-right'. Slider: 'left' or 'right'Popup: 'center', Slider: 'right'
overlaybooleanShow dark backdrop behind popup. Center always shows overlay; bottom-right defaults to offPopup center: true, bottom-right: false
initialBgColorstringInitial background color, if valid CSS color
onOpenfunctionCalled when the modal opens
onReadyfunctionCalled when the form loads inside the modal
onSubmitfunctionCalled on successful submission, receives form data
onClosefunctionCalled when the modal closes
dispatchEventsbooleanEnable CustomEvent dispatching on windowfalse
autoCloseMsnumber | nullAuto-close delay after submit (0–30000ms)null

Auto-open configuration

window.MakeFormConfig

Configure a single auto-open form:

interface MakeFormConfig {
  formId: string;                 // Form ID (8–15 alphanumeric chars + hyphens)
  embedUrl?: string;              // Optional pre-built embed URL
  popup?: AutoOpenEntry;          // Popup auto-open config
  slider?: AutoOpenEntry;         // Slider auto-open config
}
 
interface AutoOpenEntry {
  width?: number;                 // Modal width (360–800)
  position?: string;              // Popup: 'center' | 'bottom-right'; Slider: 'left' | 'right'
  overlay?: boolean;              // Show dark backdrop (popup only)
  showOnce?: boolean;             // Show only once per visitor
  doNotShowAfterSubmit?: boolean; // Don't show after submission
  autoClose?: number;             // Auto-close delay in ms (0–30000)
  hiddenFields?: Record<string, string | number | boolean>;
  dispatchEvents?: boolean;       // Enable CustomEvents
  bgColor?: string;               // Initial background color
  open?: {                        // Trigger config (omit for page load)
    trigger: 'time' | 'exit' | 'scroll';
    ms?: number;                  // For 'time': delay in ms (500–120000)
    scrollPercent?: number;       // For 'scroll': percentage (1–100)
  };
}

window.MakeFormConfigs

Array of configurations for multiple forms (max 20):

window.MakeFormConfigs = [
  {
    formId: "FORM_1",
    popup: {
      width: 500,
      showOnce: true,
      open: { trigger: "time", ms: 5000 }
    }
  },
  {
    formId: "FORM_2",
    slider: {
      width: 400,
      doNotShowAfterSubmit: true,
      open: { trigger: "scroll", scrollPercent: 75 }
    }
  }
];

Framework examples

EmbeddedForm.tsx
'use client';
 
import { useEffect, useRef } from 'react';
import Script from 'next/script';
 
export default function EmbeddedForm({ formId }: { formId: string }) {
  const containerRef = useRef<HTMLDivElement>(null);
 
  const handleScriptLoad = () => {
    if (typeof MakeForm !== 'undefined') {
      MakeForm.loadEmbeds();
    }
  };
 
  return (
    <>
      <Script
        src="https://www.makeform.ai/widgets/embed.js"
        onLoad={handleScriptLoad}
      />
      <div ref={containerRef}>
        <iframe
          data-makeform-src={`https://www.makeform.ai/e/${formId}`}
          data-makeform-auto-resize
          data-makeform-events
          loading="lazy"
          style={{ width: '100%', height: '200px', border: 0 }}
          title="Makeform form"
        />
      </div>
    </>
  );
}

Opening a popup programmatically in React:

PopupButton.tsx
'use client';
 
export default function PopupButton({ formId }: { formId: string }) {
  const openForm = () => {
    if (typeof MakeForm !== 'undefined') {
      MakeForm.openPopup(formId, {
        width: 500,
        onSubmit: ({ data }) => {
          console.log('Submitted:', data);
        }
      });
    }
  };
 
  return <button onClick={openForm}>Open Form</button>;
}

SPA considerations

In single-page applications, the SDK initializes on first page load but won’t automatically detect new embed elements added during client-side navigation.

After adding new embeds dynamically, call the appropriate load method:

// After navigating to a page with an inline embed
MakeForm.loadEmbeds();
 
// After navigating to a page with popup triggers
MakeForm.loadPopups();
 
// After navigating to a page with slider triggers
MakeForm.loadSliders();
 
// After adding or changing window.MakeFormConfig / window.MakeFormConfigs
MakeForm.loadAutoOpen();

React example — reload embeds on route change:

import { useEffect } from 'react';
import { usePathname } from 'next/navigation';
 
export function MakeFormLoader() {
  const pathname = usePathname();
 
  useEffect(() => {
    if (typeof MakeForm !== 'undefined') {
      MakeForm.loadEmbeds();
      MakeForm.loadPopups();
      MakeForm.loadSliders();
      MakeForm.loadAutoOpen();
    }
  }, [pathname]);
 
  return null;
}

Event quick reference

For detailed event documentation, see Handle Form Events.

PostMessage events

EventDescription
MakeForm.LoadedForm iframe loaded
MakeForm.SubmitSuccessForm submitted successfully
MakeForm.SetHeightContent height changed (internal)
MakeForm.LayoutReadyFirst stable layout height is ready (internal)
MakeForm.SetBackgroundColorBackground color determined (internal)
MakeForm.SubmittedPayload-free submit signal for safe auto-close (internal)

Custom DOM events

EventDetailFires when
MakeForm:open{ formId }Popup/slider opens
MakeForm:ready{ formId }Form iframe reports loaded
MakeForm:submit{ formId, data }Form submitted
MakeForm:close{ formId }Popup/slider closes

URL parameters

ParameterDescription
mk-rm-bg=trueRemove form background (transparent)
mk-align-left=1Align supported embedded form content to the left
mf_locale={locale}Request a runtime locale for system copy and paid translation overlays
__mf_emitEvents=1Enable postMessage events on full page (/f/) route
{fieldName}={value}Set hidden field values

Parameters starting with __mf_ are reserved for internal use and cannot be used as hidden field names.


Troubleshooting

Form not loading

  • Verify the form ID is correct and the form is published
  • Check that embed.js is loaded (look for the script in the Network tab)
  • Look for errors in the browser console
  • Ensure your content security policy allows iframes from makeform.ai

Height not adjusting

  • Add data-makeform-auto-resize to the iframe element
  • Use the /e/{formId} route for inline embeds
  • The SDK uses ResizeObserver to detect content changes automatically
  • If content is loaded asynchronously inside the form, height updates when the content renders

Events not firing

  • For inline embeds: add data-makeform-events to the iframe
  • For popups/sliders: add data-makeform-events to the trigger or set dispatchEvents: true
  • For full page embeds: append __mf_emitEvents=1 to the URL
  • Listen for MakeForm:* CustomEvents unless you specifically need raw postMessage payloads

Popup/slider not opening

  • Ensure the form ID matches the pattern: 8-15 alphanumeric characters and hyphens
  • Check that embed.js has loaded before calling MakeForm.openPopup()
  • On SPAs, call MakeForm.loadPopups() after adding trigger elements
  • For auto-open snippets, call MakeForm.loadAutoOpen() after changing window.MakeFormConfig