Cannot postMessage to IFrame element on Editor-X live site

Hi, I am trying to use IFrame element from EditorX. However, it seems that I cannot postMessage from my Wix page to the IFrame element.

Here are the simplest code to reproduce the issue. On my Wix page, I added the following code:

$w.onReady(function () {
 // periodically postMessage to the element
 let pingTimer = setInterval(function() { 
        console.log('sending ping to iframe');
        $w('#html1').postMessage({ type: "ping" });
    }, 1000);
});

Then, on the iFrame element, I added the following code. I.e. I only added a handler for onmessage and output logs when a message is received.

Previewing the site is OK. I could see the ‘received ping’ logs as expected.

But the ping is not received on the published site.

Note that I have tried to use incognito window and clearing the browser cache. But it didn’t help.

Also please note that it only happens on Editor X sites. The postMessage works well on the conventional editor sites.

Here is the live site that reproduces the issue:
https://opi544.editorx.io/iframetest

Thanks in advance for your help.

Another finding. If you go to the page from another page (e.g. using link), then the iFrame can receive the postmessage.

I added the following page:

https://opi544.editorx.io/iframetest/test

in which you can click the button to go the the home page

https://opi544.editorx.io/iframetest

Here is the screen shot of chrome console. The postmessages are received by the the iframe now.

Also, I think this problem appears just in this week, because around two weeks ago our code that uses postMessage to an iFrame working just fine.

I have the exact same bug! I created a simple website like you to make sure it is a bug. did you find a solution/get support ???

thanks

I have submit a support ticket. They said it has reached the development team but didn’t hear anything from them yet (already about 3 weeks passed).

@nikobarli that’s crazy. It’s such a fundamental feature, I can’t believe it’s not working for that long!!! I submitted one too, hopefully they’ll take care of it soon.

thanks for the info buddy

@hurryappnet I currently workaround this issue by making sure my pages that use the iframe, are navigated from another page. In case someone reload the page, I first redirect it to another page, and then redirect it back to the corresponding page (yes, it hurts the page loading latency…).

I am also hoping Wix fix this issue soon. As you said, its a very fundamental feature.

Preview/Live modes, and the Classic Editor / Editor X all have slightly different timing issues concerning the HtmlComponent. You need to do a bit of a handshake between the HtmlComponent and the Page to ensure both sides are ready before trying to communicate.

In your embedded code, you can “catch” the moment the script is ready, and notify the page that the embedded script is ready:

<body onLoad="ready()">
...
  function ready(){
    window.parent.postMessage({"type":"ready"}, "*");
  }

In your page code, you can catch the message from the embedded script notifying the page that the embedded script is ready.


 if(event.data.type === 'ready'){
            // HtmlComponent script is ready
        }

Also in your page code, you can send a “ready” message to inform the embedded script that the page is ready. When both sides (the page, and the HtmlComponent embedded script) are both ready, then you can start passing messages with content between the page and the embedded script.

Hi Yisrael, thanks for the response.

Actually, my production site code has already the handshake in place. The problem is, the communication path between WIX and the iframe is never established no matter how long you wait (for both direction). I also tried to put extremely long timer (e.g. 1 minute) before trying to communicate, and it failed as well.

I looked at your code and don’t see the onLoad in your embedded script. This is how the page is notified that the embedded script has been loaded and is ready.

<body onLoad="ready()">

@yisrael-wix

I created a new test page here: https://opi544.editorx.io/iframetest/home2

The Wix-side code is as follows:

$w.onReady(function () {
    setInterval(function() { 
        console.log('WIX: sending ping to iframe');
        $w('#html1').postMessage("ping");
    }, 1000);

 // when a message is received from the HTML element
    $w("#html1").onMessage( async (event) => {
 let data = event.data;
 if(data.type === 'ping') {
            console.log('WIX: received ping from iframe');
 return;         
        }
    });
});

The iframe side code is as follows:

<!DOCTYPE html>
<html>
  <head>
  <body onLoad="ready()">
      <div id="counter">inside iframe</div>
    <script type="text/javascript">
      function ready() {
        console.error('IFRAME: inside window.onload');
        window.onmessage = (event) => {
          console.error('IFRAME received ping: ', event.data);
        };

        setInterval(function() { 
          console.error('IFRAME: sending ping to WIX');
          window.parent.postMessage({ type: "ping"}, "*");
        }, 1000);

      };
    </script>
  </body>
</html>

Still not possible to have the Wix and iFrame communicate each other.

@nikobarli I’m sending this to QA for evaluation.

Not sure about you doing an “endless” interval ping (I don’t see where you stop it). Basically what’s needed is a simple handshake to establish that both sides are ready.

I tried something like the following:

Page:

$w.onReady( function () {
$w( ‘#html1’ ).postMessage( ‘hello from page’ );
$w( “#html1” ).onMessage((event) => {
console.log( ‘data from html’ , event.data);
if (event.data === ‘hello’ ) {
console.log( ‘hello from html’ );
$w( ‘#html1’ ).postMessage( ‘hello from page’ );
} else {
console.log( ‘not hello from html’ )
}
});
});

HtmlComponent:

< html >

< head >
< title > test </ title >
</ head >

< body onLoad = " ready ()" >
< script type = “text/javascript” >
window . onmessage = ( event ) => {
if ( event . data ) {
console . log ( ‘data’ , event . data );
}
}
function ready () {
window . parent . postMessage ( “hello” , “*” );
}
</ script >
</ body >

</ html >

In any case, your case isn’t working and my test case isn’t working, so let’s see what QA says.

Hi Israel,
unfortunately, I’m familiar with the handshake but the bug persists.
Again, this happens only on Editor X.
I’m a web developer myself for 5 years now and after testing multiple cases I’m 100% sure this is a bug. please follow the following steps to recreate the problem and see it for yourself:

you need to do A/B testing with 2 different attempts:

  1. copy the following website link, paste it in the address bar in a new tab and press enter :
    https://hurryappnet.editorx.io/mysite-2

open the debugger console, and see that the communication doesn’t work (when clicking the “start now” button nothing is printed to the console, meaning the communication between the iframe and the page doesn’t work. in addition, the onLoad function is being called on the iframe and prints to the console but won’t deliver the message to the page code.

  1. open the website by clicking the following link :
    https://hurryappnet.editorx.io/mysite-2

open the debugger console, and you’ll see that the communication works and that on each time the you press the button the message is delivered and printed to the console. once you do a hard refresh (ctrl+f5), it will stop working. meaning it only works when the page is being opened from a different page.

I implemented the hankshake in this website like you suggested. here is the code:

iframe code:

wix page code:

$w.onReady(function () {
$w(“#html1”).onMessage( (event) => {
console.log(event.data);
} );
});

export function button1_click(event) {
$w(“#html1”).postMessage(“Message from page code!”);
}

this is a serious problem! literally the html component/page code communication doesn’t work when using editor X.

I guess it can be fixed pretty easily considering that it does work when the page is being opened from a different page using a link.

Please let me know that you have successfully recreated the problem so we can move forward. I can’t make progress in building my website because of this issue /:

@hurryappnet Thanks for your comments. I’ve already sent this on to QA and hopefully then can enlighten us.

@yisrael-wix Hi israel, please check out my response here on this thread. I’m not using an endless ping, I’m triggering the message when a button is clicked and the problem still persists.

I’m a developer myself and I wrote you a very detailed description on how to recreate the problem to make it easier for the QA team to discover. please check it out!

@yisrael-wix

I didn’t stop the ping just to make the code shorter. In my production code, I stop the ping once the connection established (which actually requires no more than one ping when succeeded).

@yisrael-wix Any updates on this ? thank you for your help.

@yisrael-wix any update on this ?

@hurryappnet @home8723 It seems that they fixed the issue. Unfortunately, it breaks another scenario as follows:

  1. Go to the page with the iframe → everything is OK, you can postMessage to iframe and receive messages from the iFrame

  2. Click a button to move to another page (using Link or wixLocation)

  3. On that page, click another button to move back to the first page (the page with the iframe)

  4. Now you can no longer postMessage to the iFrame. The following errors is emitted:

comlink.ts:265 Uncaught (in promise) TypeError: Cannot read property 'postMessage' of null
    at Object.<anonymous> (platform.afd19439.chunk.min.js:1)
    at iframetest:105
    at Object.next (iframetest:105)
    at c (iframetest:105)
deserialize @ comlink.ts:265
w @ comlink.ts:519
Promise.then (async)
apply @ comlink.ts:442
invokeSdkHandler @ clientWorker.ts:38
(anonymous) @ index.ts:60
(anonymous) @ index.ts:69
postMessage @ VM22:3
Object.keys.reduce.c.value.c.value.l.value @ withValidation.js:42
(anonymous) @ c1dmp.js:12
eval @ VM21:3
(anonymous) @ createRegisterEvent.ts:47
(anonymous) @ tslib.es6.js:100
(anonymous) @ tslib.es6.js:81
(anonymous) @ tslib.es6.js:74
s @ tslib.es6.js:70
(anonymous) @ clientWorker.a742ae92.bundle.min.js:1
n @ comlink.ts:312

It seems that the object returned when selecting the iframe (e.g. $w(‘#iframe’)) is somehow returning null.

I put the movie demonstrating the issue here.

You can check the live site here:
https://opi544.editorx.io/iframetest

This appears to be related to a recent performance release. Niko, please try your site again.

Hurry and Niko, let me know if you have other sites with this issue so I can address the issue.