skip to Main Content

I’m using Nextjs and on my laptop the code is working as intended
when accessing the page from my Iphone it didn’t load
I’m using it to send data between iframes on two different sites
on the Nextjs project

useEffect(() => {
const handleLoad = () => {
  if (iframeRef.current) {
    iframeRef.current.contentWindow.postMessage(
      { data },
      process.env.IFRAME_LINK
    );
  }
};

if (iframeRef.current) {
  iframeRef.current.addEventListener('load', handleLoad);
}

return () => {
  if (iframeRef.current) {
    iframeRef.current.removeEventListener('load', handleLoad);
  }
};
}, [iframeRef.current]);

Again on a pc/laptop this working

The Iframe site code (Vite React)

useEffect(() => {
const handleMessage = (event) => {
  const parentURL = import.meta.env.PARENT_URL;
  if (event.origin !== parentURL) return;
  let { data } = event.data;
  console.log('received');
  setUserData(data);
};

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

2

Answers


  1. I tried the same just a change I did is

    if (iframeRef.current) {
      iframeRef.current.addEventListener('loadeddata', handleLoad);
    }
    

    I Used loadmetadata instead if load and instead of using import.meta.env.PARENT_URL; I used a static url.

    You can console or put an alert before your if (event.origin !== parentURL) return;
    for parent url it might be stuck there.
    Initially it happend with me as well.

    Login or Signup to reply.
  2. This could be due to one of the reasons below:

    • Cross-Origin Restrictions: Mobile browsers can be stricter. Ensure process.env.IFRAME_LINK and import.meta.env.PARENT_URL are correct and match the exact origin (https://your-domain.com)
    • iframe Loading: The iframe might not be fully loaded when postMessage is sent.
    • Safari Quirks: Mobile Safari sometimes needs extra handling for event listeners and postMessage.

    Ensure the iframe is loaded before sending the message in the parent (next.js):

    useEffect(() => {
      const handleLoad = () => {
        iframeRef.current?.contentWindow?.postMessage({ data }, 'https://your-iframe-site.com');
      };
    
      iframeRef.current?.addEventListener('load', handleLoad);
    
      return () => iframeRef.current?.removeEventListener('load', handleLoad);
    }, [iframeRef]);
    

    iframe (Vite React):

    Check the message origin to allow only trusted sources:

    useEffect(() => {
      const handleMessage = (event) => {
        if (event.origin !== 'https://your-parent-site.com') return;
        setUserData(event.data?.data);
      };
    
      window.addEventListener('message', handleMessage);
      return () => window.removeEventListener('message', handleMessage);
    }, []);
    

    Additional Tips:

    • Test with hardcoded origins (replace environment variables temporarily).

    • Add a slight delay in postMessage for Safari:

      setTimeout(() => iframeRef.current?.contentWindow?.postMessage({ data }, ‘https://your-iframe-site.com’), 100);

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search