Handling window.postMessage() Events Not Triggering in a React iframe

61 views Asked by At

I'm building a React iframe that is hosted on client websites. The client website passes information to the iframe using window.postMessage().

The client attempts to pass previous conversation history by making an internal call and then passing that information through the following code:

window.postMessage({
  action: "updateConversations",
  conversations: // conversation data here
}, targetOrigin);

However, no matter what I do, handleMessage is not getting triggered. The console.log inside handleMessage is not getting printed at all. I'm wondering if the delay in response from the client server is causing this issue or if it's something else.

Here is my code snippet:

useEffect(() => {
  const urlParams = new URLSearchParams(window.location.search);
  if (urlParams.has("projectID")) {
    setProjectID(urlParams.get("projectID"));
  }

  const widgetURL = `${apiURL}/widget/${urlParams.get("projectID")}`;

  async function fetchData() {
    try {
      const response = await fetch(widgetURL);
      const data = await response.json();
      setWidgetData(data.widget);
      window.parent.postMessage({ action: "getConversationData" }, data.widget.eventOriginEmbed);

      const handleMessage = (event) => {
        console.log("event.origin", event.origin);
        console.log("event.data.action", event.data.action);

        if (event.origin !== data.widget.eventOriginEmbed) 
          return;

        if (event.data.action === "updateConversations" && event.data.conversations) {
          console.log("Received by frontend", event.data.conversations);
          setConversation(event.data.conversations);
        }
      };

      window.addEventListener("message", handleMessage);
      return () => window.removeEventListener("message", handleMessage);
    } catch (error) {
      console.error(error);
    }
  }

  const cleanup = fetchData();

  return () => {
    if (typeof cleanup === 'function') {
      cleanup();
    }
  };
}, []);

I've included the necessary parts of my code. Any insights or suggestions on what might be causing handleMessage to not be triggered would be greatly appreciated.

1

There are 1 answers

0
het On

I'm not sure it would be a solution for you, but it looks not safe to call postMessage before calling addEventListener. How about calling addEventListener first before calling postMessage?

On the other hand, it looks like you are assigning a promise for cleanup, not a function. typeof cleanup === 'function' will always be false, and the cleanup call will never be executed. I think you should fix it using await.