Search code examples
javascriptreactjsnext.jsiframestreamlit

How to correctly receive postMessage events from a Streamlit iframe in a Next.js application?


I'm integrating a Streamlit app within a Next.js application by embedding the Streamlit in an iframe. My objective is to send data from the Streamlit app to the Next.js parent using window.postMessage, specifically to transmit "total tokens used" information. However, I'm encountering difficulties in capturing these messages within the Next.js app.

Problem:

Despite setting up an event listener in my Next.js app to listen for message events, and sending a message from the Streamlit app using postMessage, the messages do not seem to be received by the Next.js app. The event listener I've added does not appear to trigger upon sending the message.

Next.js Parent Code:

// Inside a React component
useEffect(() => {
  const handleMessage = (event) => {
    console.log('Received message:', event.data);
  };

  window.addEventListener('message', handleMessage);

  // Cleanup to remove event listener
  return () => {
    window.removeEventListener('message', handleMessage);
  };
}, []);

Streamlit Child Code:

# Python snippet to send message to parent
js = """
<script>
window.parent.postMessage({totalTokensUsed: 1234}, '*');
</script>
"""
st.components.v1.html(js, height=0)

What I've Tried:

  1. Ensuring both apps (Streamlit and Next.js) are up and accessible.
  2. Using the wildcard '*' for the target origin in the postMessage call for debugging purposes.
  3. Adding console logs within the message event listener to check if it's being executed, which it doesn't seem to be.
  4. Used window.parent.socket.postMessage... (as in postMessage not being received from iframe)
  5. Read postMessage documentation

Questions:

  1. Are there any known compatibility issues with postMessage communication between Streamlit iframes and a Next.js parent application?
  2. How should the postMessage call and the event listener be structured to work with Streamlit's execution model?
  3. Could CORS policies be impacting the message delivery, even when using '*' as the target origin?

Solution

  • You can check if you are accessing the correct parent. If you aren't receiving message on the first level parent by posting it on window.parent.

    Try

    window.parent.parent.postMessage