I am creating a React component that renders arbitrary HTML/JavaScript inside of an iframe set using srcDoc attribute. However, the iframe could have scripts that may potentially have errors and I would like to show an error message instead of the iframe in that case. However, the triggering of the error seems very inconsistent I’m speculating due to a timing issue. How do I ensure the error handler is triggered?
const RenderHtml = ({ htmlBlock }: { htmlBlock: HtmlBlock }) => {
const iframeRef = useRef<HTMLIFrameElement>(null);
const [hasError, setHasError] = useState<boolean>(false);
useEffect(() => {
if (!iframeRef.current) return;
const iframe = iframeRef.current;
if (iframe.contentWindow) {
iframe.contentWindow!.addEventListener("error", onIframeError);
}
return () => {
if (iframe.contentWindow) {
iframe.contentWindow!.removeEventListener("error", onIframeError);
}
}
}, [htmlBlock.html]);
const onIframeError = (event: ErrorEvent) => {
event.preventDefault();
setHasError(true);
};
return !hasError ? (
<iframe
ref={iframeRef}
srcDoc={htmlBlock.html}
style={{
border: "none",
width: "100%",
}}
></iframe>
) : (
<Alert color="danger">There was an error loading the HTML content</Alert>
);
};
2
Answers
i modified your code to use window.postMessage():
In this code, we are using window.postMessage() to send a message to the iframe when it is ready. We then add an event listener to the window object to listen for messages from the iframe. If the message received is “error”, we set the hasError state to true.
see if it works
Example: