Issue with Receiving postMessage Events in a Streamlit App Embedded in a Next.js Iframe

Hello Streamlit Community,

I’m currently working on integrating a Streamlit app within a Next.js application by embedding the Streamlit app inside an iframe. My goal is to facilitate communication between the Next.js parent and the Streamlit child iframe using the window.postMessage API. Specifically, I’m trying to send data (total tokens used) from the Streamlit app back to the Next.js app to be processed and displayed.

Problem Description

Despite setting up an event listener for message events in my Next.js app and using postMessage in the Streamlit app, I’m unable to successfully capture and log the messages as expected. The event listener seems not to be triggered by the postMessage call, or the messages are not being sent correctly from the Streamlit app.

Here’s a simplified version of my setup:

Next.js (Parent):

// React component that embeds the Streamlit app in an iframe
const handleMessage = (event) => {
  console.log('Received message:', event.data);
};

useEffect(() => {
  window.addEventListener('message', handleMessage);
  return () => {
    window.removeEventListener('message', handleMessage);
  };
}, []);

Streamlit (Child):

# Python code that attempts to send a message to the parent
js = """
<script>
window.parent.postMessage({totalTokensUsed: 1234}, '*');
</script>
"""
st.markdown(js, unsafe_allow_html=True)

Attempts to Resolve

  • I’ve confirmed that both the Streamlit app and the Next.js app are running and accessible.
  • The postMessage call in Streamlit uses ‘*’ for the target origin for testing purposes.
  • I’ve placed console logs in the event listener to verify if it’s being executed, but it appears not to be triggered at all.

Questions

  1. Are there any known issues or limitations with using postMessage between Streamlit and a parent Next.js app?
  2. Is there a specific way I should be structuring the postMessage call or the event listener to ensure compatibility with Streamlit’s execution environment?
  3. Could cross-origin policies be affecting the message delivery, even though I’m using ‘*’ as the target origin for testing?

I would greatly appreciate any insights, suggestions, or examples from anyone who has successfully implemented a similar setup or can spot what I might be doing wrong.

Thank you in advance for your help!

For those facing issues with postMessage in nested iframes, I found that my window was somehow doubly nested. The solution was to use

window.parent.parent.postMessage({totalTokensUsed: 1234}, '*');

to correctly target the outermost context.

Big thanks to Nikhil who pointed this out: Stack Overflow Answer