monaco-editor
Babel standalone
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>- React: The core library that handles components, hooks, state, etc.
- ReactDOM: Enables React to render components into the browser's DOM (i.e., the actual HTML page).
UMD stands for Universal Module Definition. It’s a JavaScript format that works universally, for example, in a browser using a <script> tag.
unpkg is a free CDN for any npm package. It allows you to load React or other packages directly in your browser.
Thus, the above code loads React directly into the browser.
<script>
try {
${compiledCode}- Here, compiledCode is plain JavaScript after JSX is transpiled. It is injected into the
<script>tag.
ReactDOM.render(React.createElement(App), document.getElementById('root'));- Step 1: Creates an element using the compiled
Appcomponent. - Step 2: Renders it into the
<div>with theid="root".
} catch (err) {
document.body.innerHTML = '<pre>' + err + '</pre>';
}
</script>- If there’s a runtime error (e.g., referencing an undefined variable), it catches the error and displays it inside the iframe.
} catch (err: any) {- Catches compile-time errors (e.g., syntax errors during Babel transpilation).
- Input: User types JSX into Monaco Editor.
- Compile: Babel transforms JSX → JavaScript.
- Embed: Wraps compiled JS in full HTML + React CDN.
- Inject: Sets the HTML into an iframe (
srcDoc). - Render: ReactDOM renders the component in the iframe.
An iframe is a small browser window embedded within your current webpage. It can load another entire webpage — with its own HTML, CSS, and JS — in complete isolation.
srcDoc -> Instead of a URL, lets you inject raw HTML directly
After user submits the solution, how do we validate it?
We get the document from iframe as:
const iframe = document.querySelector("iframe") as HTMLIFrameElement;
const iframeDoc = iframe?.contentDocument;Then we perform the logic
But we have to make some changes:
<iframe
sandbox="allow-scripts allow-same-origin"add allow-same-origin
Also if we try to access iframe.contentDocument before it's ready, we might get null so to avoid this:
const iframeDoc = iframe?.contentDocument;
if (!doc) return console.log("Iframe not ready");
...