Skip to main content
The Formbox embed script lets you render a form inline on a page, open it in a popup, or mount it as a full-page experience, all without rebuilding any form UI yourself.

Install the script

Add the script once on any page where you want to embed a form:
<script async src="https://app.formbox.app/scripts/embed.js"></script>
Once loaded, the script initializes any iframes with data-formbox-src, wires up popup triggers marked with data-formbox-open, handles iframe height syncing for inline embeds, and exposes window.Formbox for programmatic control.

Inline embed

Place an iframe with data-formbox-src wherever you want the form to appear. The script will set the src for you and inject the metadata it needs.
<script async src="https://app.formbox.app/scripts/embed.js"></script>

<iframe
  data-formbox-src="https://app.formbox.app/embed/your-form-id?dynamicHeight=1"
  loading="lazy"
  width="100%"
  title="Contact form"
></iframe>
Adding dynamicHeight=1 tells the embedded form to report its content height back to the parent page. The script listens for those messages and resizes the iframe automatically, so it grows naturally with multi-page forms, validation messages, or conditional content. This is the recommended setup for any inline embed placed inside flowing page content. You can render the same form more than once on a single page — each iframe gets a unique instance ID internally, so height events and lifecycle messages never collide. Just make sure every iframe has a meaningful title for accessibility. Inline embeds can also use the same presentation-style data attributes as popup embeds, so you do not have to switch to query parameters just to hide the title or apply color overrides.
<iframe
  data-formbox-src="https://app.formbox.app/embed/your-form-id"
  data-formbox-hide-title="1"
  data-formbox-align-left="1"
  data-formbox-background-color="#ffffff"
  data-formbox-text-color="#111827"
  data-formbox-button-background-color="#111827"
  data-formbox-button-text-color="#ffffff"
  loading="lazy"
  width="100%"
  title="Contact form"
></iframe>

Full-page embed

If the form should take over an entire page, wrap the iframe in a minimal HTML shell that fills the viewport:
<!DOCTYPE html>
<html>
  <head>
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0"
    />
    <title>Contact form</title>
    <script async src="https://app.formbox.app/scripts/embed.js"></script>
    <style>
      html,
      body {
        margin: 0;
        height: 100%;
        overflow: hidden;
      }

      iframe {
        position: absolute;
        inset: 0;
        width: 100%;
        height: 100%;
        border: 0;
      }
    </style>
  </head>
  <body>
    <iframe
      data-formbox-src="https://app.formbox.app/embed/your-form-id?dynamicHeight=1"
      title="Contact form"
    ></iframe>
  </body>
</html>
This gives the form its own dedicated page rather than embedding it inside surrounding content. Popups can be opened declaratively with data attributes on any clickable element, or programmatically with JavaScript if you need callbacks or more control.

Using data attributes

The simplest approach — no extra JavaScript required. Set data-formbox-open to your form ID and the script handles the rest:
<script async src="https://app.formbox.app/scripts/embed.js"></script>

<button
  type="button"
  data-formbox-open="your-form-id"
  data-formbox-layout="modal"
  data-formbox-width="560"
>
  Open form
</button>
The value of data-formbox-open accepts a form ID, a full embed URL like https://app.formbox.app/embed/your-form-id, or a relative path like /embed/your-form-id. You can configure the popup further with additional data attributes on the same element:
AttributeDescription
data-formbox-layoutmodal or popup
data-formbox-widthWidth in pixels or a valid CSS size string
data-formbox-titleAccessible dialog title (defaults to “Formbox popup form”)
data-formbox-hide-titleHide the form title inside the popup
data-formbox-align-leftLeft-align the form content
data-formbox-transparent-backgroundMake the form background transparent
data-formbox-overlay-opacityNumber from 0 to 1
data-formbox-close-on-overlaySet to 0, false, or no to prevent closing on overlay click

Using JavaScript

Use Formbox.openPopup() when you want programmatic control or lifecycle callbacks:
<script async src="https://app.formbox.app/scripts/embed.js"></script>

<button id="open-formbox-popup" type="button">Open popup</button>

<script>
  document
    .getElementById("open-formbox-popup")
    ?.addEventListener("click", () => {
      Formbox.openPopup("your-form-id", {
        width: 560,
        onOpen: ({ instanceId, formId }) => {
          console.log("opened", instanceId, formId);
        },
        onClose: ({ instanceId, formId }) => {
          console.log("closed", instanceId, formId);
        },
        onPageView: (page, { formId, totalPages }) => {
          console.log("page", page, "of", totalPages);
        },
        onError: ({ reason, message }) => {
          console.log(reason, message);
        },
        onSubmit: (payload, detail) => {
          console.log("submitted", payload, detail);
        },
      });
    });
</script>
The popup supports keyboard close with Escape, optional overlay-click-to-close, scroll locking while open, and automatic height syncing with internal scrolling when content exceeds the viewport. To close a popup programmatically, call Formbox.closePopup().

Styling and appearance

By default, the embed inherits the form’s saved appearance from the Formbox dashboard — background color, text color, accent color, and button colors all carry over automatically. If you need to override those styles for a specific embed, you can pass color values through data attributes, the JavaScript API, or query parameters. All three approaches support the same set of overrides:
OverrideData attributeJS optionQuery parameter
Accent colordata-formbox-accent-coloraccentColoraccentColor
Background colordata-formbox-background-colorbackgroundColorbackgroundColor
Text colordata-formbox-text-colortextColortextColor
Button backgrounddata-formbox-button-background-colorbuttonBackgroundColorbuttonBackgroundColor
Button textdata-formbox-button-text-colorbuttonTextColorbuttonTextColor
Here’s what a fully customized popup trigger looks like using data attributes:
<button
  type="button"
  data-formbox-open="your-form-id"
  data-formbox-layout="modal"
  data-formbox-accent-color="#7c3aed"
  data-formbox-background-color="#faf5ff"
  data-formbox-text-color="#4c1d95"
  data-formbox-button-background-color="#4c1d95"
  data-formbox-button-text-color="#faf5ff"
>
  Open customized form
</button>
You only need to pass overrides when you want an embed-specific look. Otherwise the form’s saved styling is used.

Query parameters

For inline embeds or manually constructed URLs, you can also pass layout options as query parameters:
https://app.formbox.app/embed/your-form-id?dynamicHeight=1&hideTitle=1&alignLeft=1&accentColor=%23111827
Additional layout parameters include hideTitle=1, alignLeft=1, and transparentBackground=1.

Dynamically inserted embeds

The script watches the DOM for newly inserted iframes that contain data-formbox-src, so in most cases you don’t need to do anything special after injecting new markup. If you want to explicitly trigger initialization after a manual DOM update:
window.Formbox?.loadEmbeds();

Events

The embed script dispatches lifecycle events on document that you can listen for:
document.addEventListener("formbox:submit", (event) => {
  console.log(event.detail.payload);
});

document.addEventListener("formbox:popup-open", (event) => {
  console.log(event.detail);
});

document.addEventListener("formbox:error", (event) => {
  console.log(event.detail.reason);
});
The available events are formbox:loaded, formbox:resized, formbox:page-view, formbox:submit, formbox:popup-open, formbox:popup-close, and formbox:error. Each event’s detail object includes the relevant formId and instanceId, plus event-specific data like height, page, totalPages, payload, or an error reason. If an embed fails to initialize, Formbox dispatches formbox:error and shows a basic fallback error state instead of leaving the embed stuck indefinitely.

JavaScript API

The script exposes window.Formbox with a handful of methods: Formbox.loadEmbeds() — Scans the page for uninitialized data-formbox-src iframes and sets them up. Useful after dynamically inserting embed markup. Formbox.openPopup(formId, options) — Opens a popup for the given form ID. Returns the popup instance ID. The options object supports:
OptionDescription
widthPopup width in pixels or a CSS size string
overlayOpacityBackdrop opacity from 0 to 1
closeOnOverlayClickWhether clicking the overlay closes the popup (default true)
hideTitleHide the form title inside the popup
alignLeftLeft-align the form content
transparentBackgroundMake the form background transparent
accentColorOverride the form’s accent color
backgroundColorOverride the form’s background color
textColorOverride the form’s text color
buttonBackgroundColorOverride the form’s button background color
buttonTextColorOverride the form’s button text color
onOpenCalled when the popup opens. Receives { instanceId, formId }
onCloseCalled when the popup closes. Receives { instanceId, formId }
onPageViewCalled on page changes. Receives (page, { formId, instanceId, totalPages })
onErrorCalled when the popup embed fails. Receives { formId, instanceId, reason, message }
onSubmitCalled on form submission. Receives (payload, { formId, instanceId })
Formbox.closePopup() — Closes the active popup, or pass a specific instance ID or form ID to close a particular one.

Tips

Always use data-formbox-src instead of setting src directly — this lets the script inject the routing metadata it needs. For inline embeds inside flowing content, include dynamicHeight=1 so the iframe resizes with the form. For popups, use data attributes when you want a simple no-JavaScript integration, and the JavaScript API when you need lifecycle callbacks. The popup and inline modes share the same hosted embed URL and runtime, so everything from page-view tracking to submit events works the same way regardless of how the form is displayed.