Created
February 28, 2025 04:53
-
-
Save ssv445/2a9fc1da93f9f0837f5714f5c6dfb68e to your computer and use it in GitHub Desktop.
Dynamically Embedding HTML in Next.js Using iframes: When working with dynamic HTML in Next.js, you might need to handle content that includes external scripts, stylesheets, and inline JavaScript. Instead of using dangerouslySetInnerHTML, which doesn’t execute scripts, a more effective solution is embedding the HTML inside an iframe.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import { useEffect, useRef, useState } from "react"; | |
| const DynamicIframe = ({ htmlContent }: { htmlContent: string }) => { | |
| const iframeRef = useRef<HTMLIFrameElement>(null); | |
| const [height, setHeight] = useState("100px"); // Default height | |
| useEffect(() => { | |
| const handleMessage = (event: MessageEvent) => { | |
| if (event.data.height) { | |
| setHeight(`${event.data.height}px`); | |
| } | |
| }; | |
| window.addEventListener("message", handleMessage); | |
| return () => window.removeEventListener("message", handleMessage); | |
| }, []); | |
| useEffect(() => { | |
| if (iframeRef.current) { | |
| const doc = iframeRef.current.contentWindow?.document; | |
| if (doc) { | |
| doc.open(); | |
| doc.write(` | |
| <html> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <style> body { margin: 0; } </style> | |
| </head> | |
| <body> | |
| ${htmlContent} | |
| <script> | |
| function sendHeight() { | |
| window.parent.postMessage({ height: document.body.scrollHeight }, "*"); | |
| } | |
| window.onload = sendHeight; | |
| window.onresize = sendHeight; | |
| </script> | |
| </body> | |
| </html> | |
| `); | |
| doc.close(); | |
| } | |
| } | |
| }, [htmlContent]); | |
| return ( | |
| <iframe | |
| ref={iframeRef} | |
| style={{ | |
| width: "100%", | |
| height: height, | |
| border: "none", | |
| overflow: "hidden", | |
| }} | |
| /> | |
| ); | |
| }; | |
| export default DynamicIframe; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import dynamic from "next/dynamic"; | |
| const DynamicIframe = dynamic(() => import("@/components/DynamicIframe"), { | |
| ssr: false, // Ensures it runs only on the client | |
| }); | |
| const Page = () => { | |
| const htmlContent = ` | |
| <h1>Hello from Iframe</h1> | |
| <p>This is dynamic content.</p> | |
| `; | |
| return <DynamicIframe htmlContent={htmlContent} />; | |
| }; | |
| export default Page; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| const Page = () => { | |
| const htmlContent = ` | |
| <h1>Hello from Iframe</h1> | |
| <p>This is dynamic content.</p> | |
| `; | |
| return <DynamicIframe htmlContent={htmlContent} />; | |
| }; | |
| export default Page; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment