Skip to content

Instantly share code, notes, and snippets.

@JLarky
Created September 10, 2024 06:21
Show Gist options
  • Save JLarky/5d5af43a163fbf120542ba07dbdbaaad to your computer and use it in GitHub Desktop.
Save JLarky/5d5af43a163fbf120542ba07dbdbaaad to your computer and use it in GitHub Desktop.
React version of Embed block for react-sdk (sdk v2) for Builder.io
// https://github.com/BuilderIO/builder/blob/21c96eff31434f51adc9ec3e6071256572cd261b/packages/sdks/src/blocks/embed/embed.lite.tsx
import { useEffect, useRef, useState } from 'react';
export interface EmbedProps {
content: string;
}
const SCRIPT_MIME_TYPES = ['text/javascript', 'application/javascript', 'application/ecmascript'];
function isJsScript(script: HTMLScriptElement) {
return SCRIPT_MIME_TYPES.includes(script.type);
}
export function Embed(props: EmbedProps) {
const elem = useRef<HTMLDivElement>(null);
const [scriptsInserted, _setScriptsInserted] = useState([] as string[]);
const [scriptsRun, _setScriptsRun] = useState([] as string[]);
const [ranInitFn, setRanInitFn] = useState(false);
function findAndRunScripts() {
if (!elem.current || !elem.current.getElementsByTagName) return;
const scripts = elem.current.getElementsByTagName('script');
for (let i = 0; i < scripts.length; i++) {
const script = scripts[i]!;
if (script.src && !scriptsInserted.includes(script.src)) {
scriptsInserted.push(script.src);
const newScript = document.createElement('script');
newScript.async = !0;
newScript.src = script.src;
document.head.appendChild(newScript);
} else if (isJsScript(script) && !scriptsRun.includes(script.innerText))
try {
scriptsRun.push(script.innerText);
new Function(script.innerText)();
} catch (m) {
console.warn('`Embed`: Error running script:', m);
}
}
}
useEffect(() => {
if (elem.current && !ranInitFn) {
setRanInitFn(true);
findAndRunScripts();
}
// eslint-disable-next-line react-compiler/react-compiler
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [elem.current, ranInitFn]);
return <div ref={elem} className="builder-embed" dangerouslySetInnerHTML={{ __html: props.content! }}></div>;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment