Embedding Reactjs in Remote Site iFrame Embedding Reactjs in Remote Site iFrame reactjs reactjs

Embedding Reactjs in Remote Site iFrame


To satisfy the Same Origin policy (prevent CORS errors), set the <iframe>'s srcdoc attribute instead of trying to write to it.

n.srcdoc = "\n    <!doctype html>\n    <head><script src='http://localhost:3001/static/js/bundle.js' type='text/javascript'></script></head>\n    <body><div id='root'></div></body>\n    </html>";

As an added bonus, you can disable the right-click context menu with:

n.contentWindow.document.addEventListener("contextmenu", function(e){    e.preventDefault();    return false;}, false);

This is completely useless as a security measure, but it's only there as a red herring. The page that shows when you open the frame on its own will not contain the content. Only do this if there's nothing in the iframe's page that the user will want to copy; it doesn't stop them from doing so, but it's really irritating if you do want to copy something.


Demo:

//Creates Divvar d = document.createElement("div");document.body.appendChild(d);//Creates iFramevar n = document.createElement("iframe");n.id = "microcom-frame";n.style.width = "100%";n.style.height = "100%";n.style.background = "transparent";n.style.position = "relative";n.style.margin = 0;n.style.border = "none";n.style.overflow ="hidden";n.style.display = "block";//Append iFrame inside Divd.appendChild(n);//Write content to iFramen.srcdoc = "<!doctype html><html><head></head><body><div id='root'>Example content</div></body></html>";


Embedding in iframe is not a good practice as for security purposes, it could be better if you use sandboxed iframe .


The script fire before the target div is read in DOM in your test environment, just change the order of the tags. See below and see the bottom for other issues what you are trying to do will probably cause when moved to the wild.

Add "async defer" to the script tag you insert in the iframe in your your initial code like so:

n.contentWindow.document.write("\n    <!doctype html>\n    <head><script async defer src='http://localhost:3001/static/js/bundle.js' type='text/javascript'></script></head>\n    <body><div id='root'></div></body>\n    </html>"),

You can just add the script tag at the end of the body you insert instead (or do booth that and put async defer on it)

Try it with srcdoc, it works even better since it doesn't even give the option to break out of the frame (which just reloads the current location in the example above)

n.srcdoc = "\n    <!doctype html>\n    <head></head>\n    <body><div id='root'></div><script async defer  src='http://localhost:3001/static/js/bundle.js' type='text/javascript'></script></body>\n    </html>"

However.

When I tried this in production it didn't load my entire app.Anything other then the inital js bundle from the /static folder in build would not load because the app looks for them relative to the widgets location.

You might solve this by making sure the js does not chunk (create react app should not split your code yet anyway, unless you are using a package to do specifically that). You also need to load all css-files and images externally in your app rather then importing them.

It may also be possible to use one of the methods for deploying a react app into a sub-directory to set an absolute base url to your app's static resources.

Also you probably want to remove registerServiceWorker() from index.js in the react app when using it like this.

If that still causes issues and you need to load it by src you could have the react app check if it is not inside a frame and kill itself or go back when unframed by some of the methods here How to identify if a webpage is being loaded inside an iframe or directly into the browser window?