Embedding a Marketo form on a Framer LP

Framer LPs support custom code, but — as with other WYSIWYG site builders — the DX is pretty unfriendly. Insert » Utility » Embed gives you a miniature textarea with a proportional font (a pet peeve) and no syntax highlighting:

Pasting a standard Marketo Forms 2.0 embed code into the textarea looks fine in Framer’s Preview mode:

But on the published LP, the form is nowhere to be found:

There’s a very clear clue in the F12 Console:

~60% of the time, this error means you have a persistent error in script load order.

Indeed, on the published page, Framer injects the HTML embed asynchronously (I assume for what they think are “performance” reasons). The Forms 2.0 library (the remote <script src=".../forms2.min.js"> thus loads in the background, while the inline <script> is executed immediately. That’s why it’ll never find MktoForms2.

In preview and in the builder, though, the HTML embed is served in the original document. Pretty confusing.

Anyway, it’s very easy to fix with the approach from my post on accurately awaiting the Forms 2.0 global object. Use this HTML block instead:

<script src="//app-sj01.marketo.com/js/forms2/js/forms2.min.js"></script>
<form id="mktoForm_9999"></form>
<script>function doOrQueueFormsStuff() {
  if (typeof MktoForms2 != "object") {
    document.addEventListener("load", doOrQueueFormsStuff, true);
  } else if (!doOrQueueFormsStuff.done) {
    document.removeEventListener("load", doOrQueueFormsStuff, true);
    doOrQueueFormsStuff.done = true;
    MktoForms2.loadForm("//app-sj01.marketo.com", "123-ABC-456", 9999)
  }
}
doOrQueueFormsStuff();
</script>
Notes

✱ The other 40% of the time, it’s a race condition, which is different because the load order is unpredictable, based on network and browser conditions. A persistent error means the order is predictable and always wrong!

✱✱ As we’ve learned before, a script-injected inline <script> must be deliberately re-run by setting its text property, so there’s nothing accidental in this setup.