I am trying to encapsulate a React application in a Web component's Shadow Root or an iFrame to build a widget for a Chatbot messenger like Intercom widget.
I´m using:
React 16.8.6
Typescript 3.5.3
Redux 4.0.4
Styled-components 4.3.2
Material-UI 4.3.3
I based my Web component choice on this React official doc (that didint mention any of my issue).
First, I encountered some style issue, with both styled-components and Material-UI, because they both put their styles in the light DOM header. But, I figured out how to deal with both issues (I can help anyone with the same problems). [SOLVED]
Then my components are rendered without a problem, but events are not working, After some research I found that when you render a react component inside Shadow DOM events will not be dispatched to react. I.e. when a user clicks on your react component nothing happens. so i used this repo to fix this issue and retarget and dispatch events to React. [PARTIALLY-SOLVED]
But unfortunately, this is not enough, because some events like onChange
don't get fixed, and some depth like Material-UI add their own events, The problem is in React it self check this issue and they are not so motivated to fix it in a near date.[ISSUE]
So I decided to move to another encapsulation alternative, the iFrame. I didn't find a helpful tuto, repo or thread yet and all existing npm modules aren't updated neither optimized for Typescript.
I need a clear way to encapsulate my app in the #document
of the iFrame
.
Please, propose a repo. or give me any idea of implementation, any idea could be very helpful.
Finally, I did encapsulate my app in the #document
of the iframe
successfully.
// Create iframe.
const iFrame: any = document.createElement("iframe")
document.body.appendChild(iFrame)
// Create react entry point.
const mountPoint = document.createElement("div")
iFrame.contentWindow.document.body.appendChild(mountPoint)
ReactDOM.render(<App />, mountPoint)
I just forgot to point on the x.contentWindow.document.body
element, instead, I pointed directly on the iframe
.