Marketo Lightbox Form on a Gatsby Project - Failed to execute 'postMessage' on 'DOMWindow' | Community
Skip to main content
New Participant
May 30, 2023
Solved

Marketo Lightbox Form on a Gatsby Project - Failed to execute 'postMessage' on 'DOMWindow'

  • May 30, 2023
  • 1 reply
  • 2176 views

This project is a GatsbyJS Project. I have a button component that takes in the id of the marketo form, and the button text that when the button is clicked, it opens up a light box that holds a Marketo form. The form renders just fine. However, after filling out a form and hitting submit, this error shows:

forms2.min.js:4 Failed to execute 'postMessage' on 'DOMWindow': The target origin provided ('https://...') does not match the recipient window's origin ('https://...').

Here is the button component (sans the styles section):

import React, { useState ,useEffect, useRef } from 'react';
import styled from 'styled-components';
import media from '../../styles/media';




const CustomTrialButton = (props) => {


 const formRef = useRef(null);

 
 useEffect(() => {
    LoadForm(props.id);

},[props.id]);

const LoadForm =(id) => {
    setTimeout(() => {
    if(typeof MktoForms2 !== 'undefined'){
        MktoForms2.loadForm(
             "https://338-HTA-134.mktoweb.com", 
             "338-HTA-134", 
             id,
             (form) => {
         formRef.current = form
        });
    } else {
        LoadForm(id)
    }
    },60)
}

function startTrial(event) {
    if(formRef && formRef.current){
        MktoForms2.lightbox(formRef.current).show();
        event.preventDefault();
    }
};

return (
<Container>
    <LightBoxButton onClick={startTrial}>{props.text}</LightBoxButton>
</Container>
);

};

I have seen that the reason this happens is because a lightbox isn't done loading and was solved by writing onload = "iFrameResize()" However, I don't know how to implement that in my react project, where the iFrame is coming from Mkto2.forms.js file. If anyone can help me with this that would be very much appreciated!

Best answer by SanfordWhiteman

The direct cause: your packager is somehow adding another Forms 2.0 IFRAME hosted on your domain.

 

See, the Forms 2.0 library automatically injects a cross-domain IFRAME hosted on the form embed domain. But you’re injecting a local copy of it as well, with the same HTML content.

 

As a result, MktoForms2 tries to reference your library. But it’s on the wrong domain (needs to be on the same domain as the form, by definition) so the postMessage that tells the IFRAME to submit is blocked for security reasons.

 

P.S. You should be using your Marketo LP domain, not <munchkin id>.mktoweb.com.

1 reply

SanfordWhiteman
New Participant
May 30, 2023
Please use the correct way to wait for MktoForms2: https://nation.marketo.com/t5/product-blogs/accurately-background-loading-the-mktoforms2-global-object/ba-p/309609

We'd also need a link to your page, not enough to go on here.
bdraweAuthor
New Participant
May 30, 2023

Thank you for responding! Here is a link: build-557df12e-bbe4-4598-a738-a7b002ad301c.gatsbyjs.io/eliminate/

I also updated the code to match what that article shows. 

import React, { useState ,useEffect, useRef } from 'react';
import styled from 'styled-components';
import media from '../../styles/media';



const CustomTrialButton = (props) => {


 const formRef = useRef(null);

 
 useEffect(() => {
    LoadForm(props.id);

},[props.id]);

const LoadForm =(id) => {
    if(typeof MktoForms2 != 'object'){
        document.addEventListener("load", LoadForm, true);
        console.log('!= object')
    } else if (!LoadForm.done){
        console.log('done')
        document.removeEventListener("load", LoadForm, true);
        LoadForm.done = true;
        MktoForms2.loadForm("//338-HTA-134.mktoweb.com","338-HTA-134", id, (form) => {formRef.current = form});
    }
    
}

function startTrial(event) {
    if(formRef && formRef.current){
        window.MktoForms2.lightbox(formRef.current).show();
        event.preventDefault();
    }
};

return (
<Container>
    <LightBoxButton onClick={startTrial}>{props.text}</LightBoxButton>
</Container>
);

};

export default CustomTrialButton;


I have also loaded the script in a global wrapper in my react project. 

SanfordWhiteman
SanfordWhitemanAccepted solution
New Participant
May 31, 2023

The direct cause: your packager is somehow adding another Forms 2.0 IFRAME hosted on your domain.

 

See, the Forms 2.0 library automatically injects a cross-domain IFRAME hosted on the form embed domain. But you’re injecting a local copy of it as well, with the same HTML content.

 

As a result, MktoForms2 tries to reference your library. But it’s on the wrong domain (needs to be on the same domain as the form, by definition) so the postMessage that tells the IFRAME to submit is blocked for security reasons.

 

P.S. You should be using your Marketo LP domain, not <munchkin id>.mktoweb.com.