I'm trying to render MUI components inside an iframe using react portal. Although they are rendered inside the iframe, they lose all thMUI components lose their styling when rendered inside a iframe using react portals. All the documentation/examples and discourse on this topic is related to older versions of MUI. This is even worse when working with ShadowDOM.


MUI is using emotion as a styling engine by default, and @emotion has a CacheProvider to config where you want to place the styles.
import React, { useState } from 'react'
import { createPortal } from 'react-dom'
import createCache from '@emotion/cache'
import { CacheProvider } from '@emotion/react'
const PreviewIframe = styled('iframe')(() => ({
    border: 'none',
    height: '100%',
    width: '100%'
}))
const PreviewPortal = (props: PreviewPortalProps) => {
    const [contentRef, setContentRef] = useState<any>(null)
    const mountNode = contentRef?.contentWindow?.document?.body
    const cache = createCache({
        key: 'css',
        container: contentRef?.contentWindow?.document?.head,
        prepend: true
    })
    return (
        <PreviewIframe ref={setContentRef}>
            {mountNode &&
                ReactDOM.createPortal(
                    <CacheProvider value={cache}>
                        {props.children}
                    </CacheProvider>,
                    mountNode
                )}
        </PreviewIframe>
    )
}
Look these links for more details. https://mui.com/material-ui/getting-started/installation/#npm https://emotion.sh/docs/@emotion/cache#container
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With