HTML Preview

Preview HTML in a restricted sandbox

Loading tool…

About HTML Previewer

HTML Previewer renders a fragment of HTML in a sandboxed frame next to the editor, so you can see the structure and the styling a browser will actually produce. Two layers stand between what you paste and what renders: a sanitizer that removes dangerous markup, and an iframe sandbox with every permission withheld.

A preview is a rendering aid, not a security tool. It answers "does this markup produce the layout I expected", and the isolation protects the page you are sitting on rather than certifying the HTML for anyone else. That matters because the restrictions also change what you see: an element the sanitizer removes leaves no trace, and a capability the sandbox withholds fails silently. Working out which layer took something is usually the fastest way to understand a preview that looks wrong.

How to use this developer tool

  1. Paste a fragment of HTML into the left pane. The frame on the right re-renders as you type; there is no button to press.
  2. Check layout and typography first, since those are what the preview reproduces faithfully.
  3. If something is missing, work out which layer removed it: an element that vanished from the markup was taken by the sanitizer, while a control that renders but does nothing was stopped by the sandbox.
  4. Replace relative paths with absolute https URLs or data URLs, because a frame rendered from inline source resolves relative references against this site's address, not against your project.
  5. Move anything interactive into a real development server. The preview cannot tell you whether a script, a form, or a stored preference works.

Worked example: what survives the sanitizer

This fragment contains four things people commonly paste: a leading style block, an inline event handler, a relative image, and a javascript: link. Exactly one of them reaches the frame intact.

Input
<style>
  body { font: 16px/1.5 system-ui; margin: 0; }
  .card { border: 1px solid #d0d7de; border-radius: 8px; padding: 16px; }
</style>
<div class="card">
  <h1 onclick="track()">Weekly report</h1>
  <img src="logo.png" alt="Logo">
  <p>Built <a href="javascript:void(0)">by hand</a>.</p>
</div>
Markup that actually reaches the frame
<div class="card">
  <h1>Weekly report</h1>
  <img src="logo.png" alt="Logo">
  <p>Built <a>by hand</a>.</p>
</div>

The style block disappeared because a style element written before any body content is parsed into the document head, and only body content is kept — move it below the div and it survives. The onclick attribute and the javascript: href were stripped, leaving an anchor with no destination. The image tag survived, but logo.png resolves against this site's address, so it will not load.

What each layer blocks, and how the failure looks

Anything the sanitizer takes is gone from the markup before rendering. Anything the sandbox withholds is still in the markup but has no effect when used.

What you wroteStopped byHow it looks
A script elementBoth layersNever runs, and is not in the frame at all
An onclick or onerror attributeSanitizerRenders normally, never reacts
An href starting with javascript:SanitizerA link with no destination
An iframe, object, or embedSanitizerAbsent, with no placeholder
A stylesheet link elementSanitizerExternal CSS never loads
A meta or base elementSanitizerNo viewport, charset, or base URL
A form with a submit buttonSandbox, no allow-formsRenders correctly; submitting does nothing
A link to another page, or a popupSandboxClicking has no visible effect
Cookies, localStorage, a same-origin fetchSandbox, no allow-same-originOpaque origin, so storage access throws
A style element after your first elementNeitherApplies; the reliable way to add CSS here
An image or font at an absolute https URLNeitherLoads as an ordinary subresource

Troubleshooting

Pasting a complete page produces almost nothing.

Why it happens The markup is re-parsed as a document and only the body content is kept. Everything in the head — the title, meta tags, stylesheet links, and any style block written there — is discarded, and attributes on the body element itself are lost with it.

Fix Paste the body content only, and move the CSS into a style element placed after your first element. If the page depends on a class set on the body tag, wrap the content in a div carrying that class instead.

A CSS file, image, or font referenced by a relative path never loads.

Why it happens The frame is rendered from inline source, so its base URL is this site's page address. A reference such as logo.png or /assets/app.css resolves against that address and requests a file that does not exist there. A base element cannot fix it, because base elements are removed.

Fix Use absolute https URLs while previewing, or inline a small asset as a data URL. Switch back to relative paths once the markup is in your project, where they resolve correctly.

Buttons render correctly but nothing happens when clicked.

Why it happens Scripts are removed by the sanitizer and would be blocked by the sandbox in any case, and form submission needs a permission the frame is not granted. The markup is intact; only the behaviour is missing.

Fix Verify behaviour in a local development server or a browser devtools scratch page. Use this preview for the parts it can answer: structure, spacing, typography, and how a layout reflows.

The preview looks correct, so the HTML must be safe.

Why it happens The preview strips dangerous markup so that this page stays intact. That is a defence of the viewer, not an audit of the document.

Fix Treat this as a rendering aid only. Review untrusted HTML with a real sanitizer configured for your application, a Content Security Policy, and a security review. A clean-looking preview is not evidence of anything about the original markup.

When this tool is the right choice

  • Checking the structure and spacing of an email template or a static fragment without setting up a server.
  • Reading markup someone sent you, or recovered from a database column, without letting it run.
  • Trying a small CSS change against real markup, using a style element placed after the content.
  • Confirming what a fragment looks like once scripts are gone, which is roughly what a text-mode reader or a strict email client will show.

When to use something else

  • Testing an application. Scripts, forms, storage, and navigation are all disabled by design; run it against a development server instead.
  • Assessing whether markup is safe to publish. The sandbox protects this page, not your users, and no vulnerability check is performed.
  • Previewing a rendered Markdown document. The Markdown Previewer converts the source first and is the right tool when your input is Markdown.

Privacy and data handling

The markup is sanitized and rendered in this browser tab and is never uploaded. The frame carries a sandbox attribute that grants nothing at all, so the content runs no scripts, submits no forms, opens no windows, navigates nowhere, and cannot reach cookies, storage, or this site's origin. Absolute image and font URLs are still fetched as ordinary subresources, so a remote server can see the request.

Related developer tools

Frequently asked questions

Does the preview execute JavaScript?

No, and two independent layers make sure of it. Script elements are removed from the markup before rendering, and the frame is created with an empty sandbox attribute, which withholds script execution along with every other permission.

Why can the preview load an image but not a stylesheet?

The two are stopped by different things. An image at an absolute URL is an ordinary subresource and loads fine. A stylesheet is normally attached with a link element, and link elements are removed by the sanitizer, so the request is never made. Inline style rules are the way to add CSS here.

Can I test how my page behaves on a phone?

You can resize the window and watch the layout reflow, which covers most responsive CSS. What you cannot do is set a viewport meta tag, because meta elements are removed, so anything that depends on the mobile viewport scale will not reproduce.

Is the preview a security scanner?

No. It renders markup with the dangerous parts removed so that you can look at it safely. It does not analyse the input, does not report what it removed, and gives no opinion on whether the original document is safe in another context.

Why did my document lose everything above the first visible element?

Only body content is rendered. The head of a document, including the title, meta tags, stylesheet links, and any style block placed there, is dropped during sanitizing, as is any attribute written on the body tag itself.

Will what I see here match a real browser?

The layout and styling come from the same rendering engine you are using right now, so they match that browser closely. They will not match a different browser, an email client, or a reader with its own stylesheet, and the frame adds a small reset of its own for the margin and colour scheme.