Open ryanseddon opened 1 year ago
For Next.js
and tailwindCSS
, I cannot guarantee it will work consistently
const { document: doc } = useFrame();
useLayoutEffect(() => {
// this covers development case as well as part of production
document.head.querySelectorAll("style").forEach((style) => {
const frameStyles = style.cloneNode(true);
doc?.head.append(frameStyles);
});
// inject the production minified styles into the iframe
if (process && process.env.NODE_ENV === "production") {
document.head.querySelectorAll('link[as="style"]').forEach((ele) => {
doc?.head.append(ele.cloneNode(true));
});
document.head
.querySelectorAll('link[rel="stylesheet"]')
.forEach((ele) => {
doc?.head.append(ele.cloneNode(true));
});
}
}, [doc]);
@aboveyunhai What version of next and what version of this lib are you running?
I'm running 13.1.1 and 5.2.6. All I get is a blank screen. If I regress to 4.1.3 of the lib. It works, but then I don't get the useFrame helper.
Found out here, that it's possibly a state issue: https://github.com/ryanseddon/react-frame-component/issues/192
I have partial success but then
const { document: doc } = useFrame();
Outputs the same as document. Both giving the same parent html and not the parent AND iframe.
Too many issues. If you could supply the full code, would be great! Thanks
@paulm17 it's a react issue, you need to call useFrame() inside the instead of at the same level.
const Inner = () => {
useFrame();
}
const Outer = () => {
// useFrame(); call hook here will fail because it's outside of <Frame />
<Frame>
<Inner/>
</Frame>
}
@aboveyunhai Thanks for the quick reply.
That's what I needed, I've written a wrapper function.
My code in case this helps someone else.
interface wrapperProps {
children: React.ReactNode
}
function Wrapper({children}: wrapperProps) {
const { document: doc } = useFrame();
document.head.querySelectorAll("style").forEach((style) => {
const frameStyles = style.cloneNode(true);
doc?.head?.append(frameStyles);
});
return <>{children}</>
}
This is how I'm using it in my proof of concept app.
const Home: NextPage = () => {
const [isMounted, setMounted] = useState(false)
useEffect(() => {
setMounted(true)
}, [])
return (
<>
<Head>
<title>Create T3 App</title>
<meta name="description" content="Generated by create-t3-app" />
<link rel="icon" href="/favicon.ico" />
</Head>
{isMounted && <Frame
id="frame"
style={{
border: "none",
width: "100%",
height: "100vh",
}}
>
<Wrapper>
<Sortable/>
</Wrapper>
</Frame>}
</>
);
};
I saw the examples from @ryanseddon but perhaps they work for CRA only? 🤷♂️
Anyway, I now have the latest 5.2.6 working with the help from the other thread.
@paulm17 you are missing my production insert part, so it will only work on dev, if you use build step npm run build, npm run start
, the production probably will miss all the stylings.
proof of concept app.
Thanks, but you missed the part where I said ^. The app won't ever see production.
If anyone is using react-jss. This can help:
import { create } from 'jss';
import { ReactNode } from 'react';
import { useFrame } from 'react-frame-component';
import { JssProvider } from 'react-jss';
import preset from 'jss-preset-default';
const JssProviderWrapper = ({ children }: { children: ReactNode }) => {
const { document } = useFrame();
const jss = create({ insertionPoint: document.head });
jss.setup(preset());
return
export default JssProviderWrapper;
Then use it:
```tsx
const App = () => (
<Frame initialContent={initialContent}>
<JssProviderWrapper>
<MyApp />
</JssProviderWrapper>
</Frame>
);
How to load css from installed packages(node_modules)?
For example: import '@ezy/ui/styles.css';
How to load this css inside iframe, currently in link tag only public route css is working.
This project gets a lot of questions on how to make CSS work inside the iframe from various CSS-in-JS libraries to CSS modules, SCSS etc.
Add some good examples covering how this can be done in the read me.
See latest issue with demo and code examples on solving that.