JavaScript Document parseHTMLUnsafe() Method

Beginner
⏱️ 12 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline 2025
Static method

What You’ll Learn

Document.parseHTMLUnsafe() is a static method that parses HTML into a new Document with optional sanitization. Learn MDN’s injection-sink warnings, when to prefer parseHTML(), TrustedHTML + Trusted Types, default and custom Sanitizer options, declarative shadow roots, and five try-it labs.

01

Kind

Static method

02

Returns

Document

03

Args

input, options

04

Default

No sanitizer

05

Shadow DOM

Declarative roots

06

Status

Baseline 2025

Introduction

Sometimes you need a full Document from an HTML string—not just inject into one element. Document.parseHTMLUnsafe(input, options) creates that Document, optionally filters unwanted tags, and supports declarative shadow roots in the input (MDN).

The “Unsafe” suffix is deliberate: without a sanitizer, every HTML entity in the string is injected. MDN warns this is an injection sink and a possible XSS vector when the input comes from attackers. On browsers where it exists, MDN says parseHTML() should almost always be used instead.

⚠️
Injection sink (MDN)

Mitigate risk by passing TrustedHTML objects and enforcing Trusted Types with the require-trusted-types-for CSP directive. If you cannot use TrustedHTML, the next safest option is parseHTMLUnsafe(html, { sanitizer: "default" }) or parseHTML().

Related tutorials: parseHTML(), setHTML(), setHTMLUnsafe(), Document constructor.

Understanding Document.parseHTMLUnsafe()

A static method on Document—call Document.parseHTMLUnsafe(...), not on live document instances.

  • inputTrustedHTML instance or HTML string (MDN).
  • options.sanitizer — optional Sanitizer, SanitizerConfig, or "default". If omitted, no sanitizer runs (MDN).
  • Returns — a new Document with text/html, UTF-8, about:blank (MDN).
  • Declarative shadow roots — parsed; only the first per host is created (MDN).
  • Does not enforce XSS removal — unlike parseHTML() (MDN).
  • TypeError — invalid sanitizer config or value (MDN).

📝 Syntax

JavaScript
Document.parseHTMLUnsafe(input)
Document.parseHTMLUnsafe(input, options)

Parameters

  • inputTrustedHTML or HTML string to parse (MDN).
  • options.sanitizer (optional) — Sanitizer, SanitizerConfig, or "default" (XSS-safe default config). If omitted, no sanitizer is used (MDN).

Return value

A Document (MDN).

Exceptions

  • TypeError — invalid SanitizerConfig, string other than "default", or non-Sanitizer value (MDN).

Common patterns

JavaScript
const html = '<p>Hello</p><script>alert(1)</script>';

// No sanitizer — injection sink (trusted HTML only!)
const doc = Document.parseHTMLUnsafe(html);

// Default XSS-safe sanitizer (MDN)
const safeDoc = Document.parseHTMLUnsafe(html, { sanitizer: "default" });

// TrustedHTML — policy already sanitized
const trusted = policy.createHTML(html);
const trustedDoc = Document.parseHTMLUnsafe(trusted);

// Custom sanitizer — can allow script unlike parseHTML() (MDN)
const sanitizer = new Sanitizer({ elements: ["div", "p", "script"] });
const customDoc = Document.parseHTMLUnsafe(html, { sanitizer });

⚡ Quick Reference

GoalCode / note
Parse trusted HTMLDocument.parseHTMLUnsafe(html)
XSS-safe filteringDocument.parseHTMLUnsafe(html, { sanitizer: "default" })
User HTML (MDN)Prefer Document.parseHTML(html)
Custom sanitizerDocument.parseHTMLUnsafe(html, { sanitizer })
Feature-detecttypeof Document.parseHTMLUnsafe === "function"
MDN statusBaseline 2025 (Sep 2025)

🔍 At a Glance

Four facts about Document.parseHTMLUnsafe().

Call
Document.parseHTMLUnsafe

Static

Returns
Document

New tree

Default
no filter

Injection sink

Status
baseline

2025 new

📋 parseHTMLUnsafe() vs parseHTML()

Document.parseHTMLUnsafe()Document.parseHTML()
Default behaviorInject all HTMLAlways strip XSS-unsafe
Sanitizer optional?Yes (omit = none)Always sanitizes
TrustedHTMLYes (MDN)Not Trusted Types gated (MDN)
MDN for user HTMLAvoidAlmost always use
MDN statusBaseline 2025Limited availability

Examples Gallery

Examples follow MDN Document: parseHTMLUnsafe(). Use only trusted HTML in labs without a sanitizer. Never paste attacker-controlled strings.

📚 Getting Started

Parse trusted HTML into a new Document.

Example 1 — Parse trusted HTML (no sanitizer)

MDN: without a sanitizer, all entities are injected—use only for trusted markup.

JavaScript
const html = '<p>Hello</p><strong>Trusted markup</strong>';
const doc = Document.parseHTMLUnsafe(html);

console.log(doc.body.innerHTML);
// "<p>Hello</p><strong>Trusted markup</strong>"
Try It Yourself

How It Works

The detached Document holds the parsed subtree. Nothing runs until you import nodes into a live document.

Example 2 — Unsafe vs safe: parseHTML()

Same string—parseHTMLUnsafe keeps markup; parseHTML strips XSS-unsafe tags (MDN).

JavaScript
const html = '<p>Hi</p><script>alert(1)</script>';

const unsafeDoc = Document.parseHTMLUnsafe(html);
const safeDoc = Document.parseHTML(html);

console.log({
  unsafe: unsafeDoc.body.innerHTML, // may include <script> node
  safe: safeDoc.body.innerHTML      // script removed
});
Try It Yourself

How It Works

MDN: parseHTML() always removes XSS-unsafe entities. That is why it is the default choice for untrusted input.

📈 Sanitizer & Detection

Add filtering when you cannot use parseHTML().

Example 3 — sanitizer: "default" (MDN)

Next safest option when you must call the Unsafe API without TrustedHTML.

JavaScript
const html = '<p>Safe</p><script>alert(1)</script>';
const doc = Document.parseHTMLUnsafe(html, { sanitizer: "default" });

console.log(doc.body.innerHTML); // script stripped
Try It Yourself

How It Works

MDN: "default" applies the XSS-safe default Sanitizer configuration.

Example 4 — Custom Sanitizer

Allow only specific elements when you control the allow-list (MDN).

JavaScript
const html = '<div><p>Hi</p><button>Go</button></div>';
const sanitizer = new Sanitizer({ elements: ["div", "p"] });

const doc = Document.parseHTMLUnsafe(html, { sanitizer });
console.log(doc.body.innerHTML); // button removed
Try It Yourself

How It Works

Unlike parseHTML(), a custom sanitizer here can allow tags that the safe API would always strip if they are XSS-unsafe (MDN).

Example 5 — Feature-detect and prefer parseHTML()

Choose the safest available parser at runtime.

JavaScript
function parseHtmlToDocument(html, { trusted = false } = {}) {
  if (!trusted && typeof Document.parseHTML === "function") {
    return Document.parseHTML(html);
  }
  if (typeof Document.parseHTMLUnsafe === "function") {
    return Document.parseHTMLUnsafe(
      html,
      trusted ? undefined : { sanitizer: "default" }
    );
  }
  return new DOMParser().parseFromString(html, "text/html");
}

const doc = parseHtmlToDocument("<p>OK</p>");
console.log(doc.body.textContent);
Try It Yourself

How It Works

Prefer parseHTML() for untrusted strings. Reserve bare parseHTMLUnsafe() for trusted HTML or TrustedHTML pipelines.

🚀 When This API Exists

  • Declarative shadow DOM — parse HTML with <template shadowroot> into a Document (MDN).
  • TrustedHTML pipelines — input already passed through a Trusted Types policy (MDN).
  • Server-trusted fragments — CMS HTML you fully control (still audit carefully).
  • Custom sanitizer allow-lists — when parseHTML() strips too aggressively.
  • Not for raw user HTML — MDN: use parseHTML() or setHTML() instead.
  • Preview Documents — inspect parsed trees before importing nodes into the live page.

🧠 How parseHTMLUnsafe() Builds a Document

1

Receive input

TrustedHTML or string passed to Document.parseHTMLUnsafe (MDN).

Input
2

Optional sanitizer

Skip, use "default", or pass a custom Sanitizer (MDN).

Filter?
3

Parse into Document

Declarative shadow roots honored; first root per host wins (MDN).

Parse
4

Return Document

text/html, UTF-8, about:blank. Import nodes with importNode when ready.

📝 Notes

  • Baseline 2025 on MDN — newly available since September 2025. Feature-detect on older browsers.
  • Not Deprecated, Experimental, or Non-standard — defined in the HTML specification.
  • Injection sink: no sanitizer by default; XSS risk with attacker-controlled strings (MDN).
  • MDN: almost always prefer parseHTML() when supported for user HTML.
  • Use TrustedHTML + require-trusted-types-for CSP to centralize sanitization audits (MDN).
  • Related: parseHTML(), setHTML(), setHTMLUnsafe(), JavaScript hub.

Browser Support

Document.parseHTMLUnsafe() is Baseline Newly available (MDN: across latest browsers since September 2025). Feature-detect on older engines. Logos use the shared browser-image-sprite.png sprite from this project.

Baseline 2025

Document.parseHTMLUnsafe()

Parse HTML into a Document — optional sanitization, supports declarative shadow roots.

Baseline Newly available 2025
Google Chrome Supported in current releases — feature-detect older
Yes
Microsoft Edge Supported in current releases — feature-detect older
Yes
Mozilla Firefox Supported in current releases — feature-detect older
Yes
Apple Safari Supported in current releases — feature-detect older
Yes
Opera Follow Chromium support
Yes
Internet Explorer Not supported — use DOMParser + sanitization
No
parseHTMLUnsafe() Baseline

Bottom line: Detect typeof Document.parseHTMLUnsafe === "function". Prefer parseHTML() for user content. Use TrustedHTML or sanitizer: "default" when you must call this API.

Conclusion

Document.parseHTMLUnsafe() parses HTML strings into a new Document with optional sanitization. MDN treats it as an injection sink—prefer parseHTML() for user content, or use TrustedHTML and sanitizer: "default" when you must call the Unsafe API.

Continue with adoptNode(), parseHTML(), setHTML(), setHTMLUnsafe(), or the JavaScript hub.

💡 Best Practices

✅ Do

  • Prefer Document.parseHTML() for untrusted HTML (MDN)
  • Use TrustedHTML + Trusted Types CSP for injection sinks
  • Pass { sanitizer: "default" } when calling Unsafe without TrustedHTML
  • Feature-detect before calling in production
  • Reuse a Sanitizer instance for repeated configs (MDN)

❌ Don’t

  • Pass raw user strings without sanitization (MDN XSS warning)
  • Assume “Unsafe” only means shadow DOM—it means no default filter
  • Skip parseHTML() when both APIs exist and input is untrusted
  • Import parsed nodes into the live DOM without reviewing markup
  • Confuse static parseHTMLUnsafe with setHTMLUnsafe

Key Takeaways

Knowledge Unlocked

Five things to remember about parseHTMLUnsafe()

Static parser — injection sink by default; prefer parseHTML().

5
Core concepts
⚠️02

Default

no filter

MDN
📄03

Returns

Document

text/html
04

Prefer

parseHTML

User HTML
🛡05

Status

baseline

2025

❓ Frequently Asked Questions

It is a static method that parses HTML input into a new Document instance. Unlike parseHTML(), it does not sanitize by default — all HTML entities in the input are injected unless you pass a sanitizer (MDN).
No. MDN marks Document.parseHTMLUnsafe() as Baseline 2025 (newly available since September 2025). It is not Deprecated, Experimental, or Non-standard.
MDN: almost always. Document.parseHTML() always removes XSS-unsafe HTML entities. Use parseHTMLUnsafe() only for trusted HTML, TrustedHTML workflows, declarative shadow roots, or controlled cases with an explicit sanitizer.
MDN: content type "text/html", character set UTF-8, and URL "about:blank" — same as parseHTML().
No by default. MDN warns it is an injection sink and a possible XSS vector. Mitigate with TrustedHTML + Trusted Types CSP, or pass sanitizer: "default" / a custom Sanitizer.
Optional Sanitizer, SanitizerConfig, or the string "default" (XSS-safe default config). If omitted, no sanitizer runs and all HTML is injected (MDN).
Did you know?

MDN says the suffix “Unsafe” means parseHTMLUnsafe() does not enforce removal of all XSS-unsafe HTML entities—unlike parseHTML(). You can still pass a sanitizer, but if you omit it, every entity in the string is injected into the new Document.

Next: adoptNode()

Learn how to move nodes from another document into the current page.

adoptNode() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

6 people found this page helpful