iframe Render Tester
Paste HTML and watch it render inside a sandboxed iframe at any viewport, then copy the exact embed snippet. · Updated
Debugging a layout in the page you are building means fighting the page: inherited styles, a shared viewport width, and one broken tag that can reflow everything. An iframe removes all three. Its srcdoc attribute takes a whole document as a string, so the markup you paste gets a clean document, an isolated cascade, and a viewport whose width you set — which is how a 375px breakpoint becomes something you can look at without resizing the browser or opening devtools. The sandbox attribute is the other half. With no tokens it blocks scripts, forms, popups, dialogs, and plugins; every token you add hands one capability back, and toggling them one at a time turns a vague "the embed does not work" into a specific missing permission. This tool writes both halves for you: it escapes your markup into srcdoc, assembles the sandbox list, and prints the finished tag, so the preview above is not an approximation of the embed — it is the embed, parsed back out of the snippet you are about to copy.
Common errors and fixes
Blocked script execution in 'about:srcdoc'
The frame's sandbox has no allow-scripts token. Turn on sandbox: allow-scripts, or leave it off deliberately to check the layout without JavaScript.
Blocked form submission to '' because the form's frame is sandboxed
Turn on sandbox: allow-forms. Without it a submit is refused, which looks like a dead button.
Ignored call to 'alert()'. The document is sandboxed
Turn on sandbox: allow-modals, or replace the dialog with something you can see in the render, such as writing to an element.
Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window'
Storage needs an origin, and a sandboxed frame has none. Turn on allow-same-origin; on your own page combine it with allow-scripts only for markup you trust, because together they are no sandbox at all.
Framing 'https://example.com/' violates the following Content Security Policy directive: "frame-ancestors *"
The framed page names the origins allowed to embed it, and a sandboxed frame without allow-same-origin has no origin for the policy to match; even * matches real http(s) origins only. Turn on sandbox: allow-same-origin: the frame then has an origin and the page loads, with its scripts too when allow-scripts is on. The copied snippet needs the same tokens wherever it is pasted. If the page is yours, send no frame-ancestors instead of *: it allows everyone anyway, and without it sandboxed embeds load too.
Refused to display 'https://example.com' in a frame
That page's X-Frame-Options or CSP frame-ancestors header forbids framing, and no attribute on your side overrides it. Only the site's own server can allow it.
Blank preview after pasting a full page
A document with its own <!doctype html> is used as-is rather than wrapped, so a missing <body> or an unclosed <head> tag renders as nothing. Run it through the HTML Formatter to find the unbalanced tag.
Options
| Option | Description |
|---|---|
| Viewport | The width and height given to the iframe. Width is what your media queries respond to, so this is how you see a breakpoint without resizing the window. |
| Custom width (px) | Used when Viewport is set to Custom size. Clamped to 120–2560px. |
| Custom height (px) | Used when Viewport is set to Custom size. Clamped to 120–2560px. |
| Wrap fragment in a document | Adds <!doctype html>, a UTF-8 charset, and a responsive viewport meta around your markup. Skipped automatically when you paste a whole document. |
| Colour scheme | Sets color-scheme on the wrapper document, so prefers-color-scheme rules and form controls render in the mode you want to test. |
| sandbox: allow-scripts | Lets <script> in the frame run. Off means the markup renders but nothing executes, which is how you tell a layout bug from a script bug. |
| sandbox: allow-forms | Lets a form submit. Off means submissions are blocked, so you can render a form without it navigating anywhere. |
| sandbox: allow-same-origin | Keeps the frame on the embedding page's origin. Combined with allow-scripts it is no sandbox at all, so on your own page use both only for markup you trust. The preview here runs on a separate origin that holds nothing, so it honours both. This token is also what lets a framed page that sends frame-ancestors (even *) load: without it the frame has no origin for that policy to match. |
| sandbox: allow-popups | Lets the frame open windows with target=_blank or window.open. Off is why a link in a sandboxed frame can look dead. |
| sandbox: allow-modals | Lets the frame call alert, confirm, and prompt. Off is why those calls return silently instead of showing a dialog. |
FAQ
What does this tool actually render?
Your markup, placed in the srcdoc attribute of a sandboxed iframe. The preview and the snippet in the output panel are the same thing: the snippet is parsed back and rendered, so what you see is what you would ship.
Why use an iframe instead of dropping the HTML on the page?
Isolation. Inside a frame the markup gets its own document, its own CSS cascade, and its own viewport width, so a global stylesheet cannot leak in and a stray closing tag cannot break the surrounding page. It is also the only way to see a media query fire at 375px without resizing your browser.
Why does the viewport width matter more than the height?
Because media queries and container-relative units respond to the frame's width. Setting the viewport to 375 × 667 makes the frame a 375px-wide viewport, which is what a phone breakpoint measures — the height only decides how much you see before scrolling.
What do the sandbox flags do?
A sandbox attribute with no tokens blocks everything: scripts, forms, popups, dialogs, and plugins. Each token you add gives one capability back. allow-scripts lets script tags run, allow-forms lets a form submit, allow-popups lets target=_blank open, and allow-modals lets alert and confirm show. Turning them off one at a time is the fastest way to find which capability a broken embed is missing.
Where does the preview actually run?
In a frame on a separate origin, the site's workers.dev copy, that holds nothing of yours: no drafts, no history, no cookies. Your snippet is pasted into a blank page there, the same way you would paste it into your own page, so the preview honours every sandbox token you choose, including allow-same-origin together with allow-scripts. On the site's own origin that pair would let pasted or shared markup read and rewrite the page around it. If that host cannot be reached, for example offline, the tool falls back to an in-page sandboxed frame, drops allow-same-origin whenever allow-scripts is on, and says so.
My script does nothing in the preview. Is it broken?
Check allow-scripts first, then remember what a fresh sandboxed document does not have: no parent variables, no localStorage without allow-same-origin, no alert without allow-modals, and no cookies. Scripts that depend on any of those need the matching token, or need rewriting.
Can I test whether someone else's site can be embedded?
No, and that is a different question. Framing another origin is refused by its X-Frame-Options or Content-Security-Policy frame-ancestors headers, which only the server sends. Paste the response headers into the HTTP Headers Inspector to read them; this tool renders markup you supply.
Why does a page framed inside my markup show an error icon?
Because that page sends a frame-ancestors policy and the preview frame has no origin. A sandbox without allow-same-origin gives the frame an opaque origin, and no source in the policy matches one, not even *, which matches real http(s) origins only. Browsers then refuse the load and draw the error icon; the copied snippet behaves the same wherever it is pasted. Turn on allow-same-origin and the page loads here, with allow-scripts too if it needs its own JavaScript; give the copied snippet the same tokens. If the page is yours and frame-ancestors * is all it sends, send no frame-ancestors at all: * allows every site anyway, and without the header sandboxed embeds work too.