Not receiving data from postMessage in embedded iframe

I am trying to use the postMessage API to receive and send data to an embedded iframe in my wix site. The desired end result is being able to pass utm params from wixLocation to the iframe. I am receiving data on other sites using this iframe so the problem seems to be with the wix/velo code. Would appreciate any help on this.

here is the velo code:

$w . onReady ( function () {
$w ( “#html1” ). onMessage ( ( event ) => {
console . log ( Message received by page code: ${ event . data });
} );
} );

and in the HTML component (React code):

useEffect(() => {
window.parent.postMessage(‘message from iframe’, ‘*’);
}, []);

Did you take a look into the VELO-API-Docs?

/* * * * * * * * * * * * * * * * * * * * * * * * *
 * Paste the following into the HTML Component:  *
 * * * * * * * * * * * * * * * * * * * * * * * * *

<!doctype html>
<html>
<head>

<script type="text/javascript">
function init () {
  // when a message is received from the page code
  window.onmessage = (event) => {
    if (event.data) {
      console.log("HTML Code Element received a message!");
      insertMessage(event.data);
    }
  }
}

// display received message
function insertMessage(msg) {
  document.getElementById('demo').innerHTML = msg;
  sendReturnMessage("Message from the HTML Component!");
}

// send message to the page code
function sendReturnMessage(msg) {
  window.parent.postMessage(msg, "http://mysite.com");
}
</script>

</head>

<body onload="init();" style="background-color:lightgray;">
<h1>HTML Component Test</h1>
<p id="demo">Message will go here</p>
</body>
</html>

 * * * * * * * * * * * * * * * * * * * * * * * * *
 * This is the page code:                        *
 * * * * * * * * * * * * * * * * * * * * * * * * */

$w.onReady(function () {
  // when a message is received from the HTML Component
  $w("#myHtmlComponent").onMessage( (event) => {
    console.log(`Message received by page code: ${event.data}`);
  } );
} );

export function messageSendButton_onClick() {
  // send message to the HTML Component
  $w("#myHtmlComponent").postMessage("Message from page code!");
}

Expand your code inside your HTML-Component, like shown in the EXAMPLE.

Does other React functionality work for you there?

Yes. The React part is working fine. I am getting the data on another website that I’ve written with HTML and JS using the exact same code for the iframe.

And the react component is rendered and functioning on the wix site, just not the postMessage

@yael-luria if you add a console.log(‘USE-EFFECT-FIRE’) to the useeffect hook, does it log anything?

@jonatandor35 Yes, it logs ‘USE-EFFECT-FIRE’

@yael-luria If the useEffect triggers, I don’t see a reason why you don’t receive it on the parent page.

Maybe you post it to the page before the $w is ready. try to look into it

I added a console.log(‘READY’) inside the onReady function:

$w . onReady ( function () {
console . log ( “READY” )
$w ( “#html1” ). onMessage ( ( event ) => {
console . log ( Message received by page code: ${ event . data });
} );
} );

it prints ‘READY’ to the console before the ‘USE-EFFECT-FIRE’

Yes, I looked into them. The velo code is taken exactly from there.
The React code is what I wrote in the post and it behaves similarly to the html in the EXAMPLE. That code is run on the initial render of this component (you can read about the useEffect hook here ) and is working as expected (I’m able to use postMessage to send data to other websites), so the problem is most definitely in the wix site.

@yael-luria Still did not understand the problem if i am honest :roll_eyes:

Tested this one successfuly…

$w.onReady(function() {console.log("READY");
    $w("#html1").onMessage((event) => {
        console.log(`Message received by page code: ${event.data}`);
    });
    $w("#button1").onClick((event)=>{
        $w("#html1").postMessage("Message from page code!");
    });
});
<html>
    <head>        
      <script>
          function init () {
              // when a message is received from the page code
              window.onmessage = (event) => {console.log(event)
                  if (event.data) {
                      console.log("HTML Code Element received a message!");
                      insertMessage(event.data);
                      alert(event.data);
                  }
              }
              // display received message
              function insertMessage(msg) {
                document.getElementById('demo').innerHTML = msg;
              }
          }            

          window.parent.postMessage('message from iframe', '*');

      </script>
      
      </head>

      <body onload="init();" style="background-color:grey;">
         <p id="demo">Message will go here</p>
     </body>
</html>

Everything works like expected.

@russian-dima Yeah, I tried now and see that it works. So there must be a problem with the connection between the React code and the wixsite when using postMessage, even though the react component is otherwise functioning as expected. Anyway, I think I will just attach a vanilla js script to the iframe for this purpose so I’m now basically set. Thank you.

If you want to use React (or other frameworks, or plain JS web components) you might want to consider using the Wix Custom Element . Take a look at the Custom Element examples to see how they’re used.

Adding to Yisrael’s comment, that if for some reason you need it to be in an iframe only, you still can create an iframe through a custom element and use the relevant NPMs for React.