Today I learned that browsers now have a built-in HTML Sanitizer API. I’ve shipped DOMPurify more times than I can count just to safely inject user content, so this is welcome news.

Browser support

Note: This is still experimental, so feature-detect before using:

javascript
if ('Sanitizer' in window) {
  element.setHTML(content);
} else {
  // Fall back to DOMPurify or other library
}

Check MDN and caniuse for current support. As of late 2025, it’s available in Firefox 148 nightly only, and no other browsers, so you’ll be stuck with DOMPurify or another library for the short term!

The problem it solves

Using innerHTML with user-provided content lets arbitrary JavaScript run in your page. Any string that reaches innerHTML can contain <script> tags or event handlers that execute immediately. DOMPurify solves this, but it means shipping an extra dependency just to strip dangerous markup. Now browsers can handle it natively.

Basic usage

The simplest approach uses setHTML() on any element:

javascript
const untrustedString = 'Hello <script>alert("xss")</script> World!';
const element = document.getElementById('target');

element.setHTML(untrustedString);
console.log(element.innerHTML); // "Hello  World!" - script removed!

The browser automatically strips out dangerous elements like <script>, event handlers like onclick, and other XSS vectors.

Customizing what’s allowed

You can create a Sanitizer object to control exactly which elements and attributes are permitted:

javascript
// Only allow paragraphs and links with href
const sanitizer = new Sanitizer({
  elements: ['p', 'a'],
  attributes: ['href']
});

element.setHTML(userContent, { sanitizer });

Or start with defaults and tweak:

javascript
const sanitizer = new Sanitizer();
sanitizer.removeElement('img');  // No images allowed
sanitizer.allowAttribute('class');  // But classes are fine

When you need more danger

For trusted content that needs unsafe elements, there’s setHTMLUnsafe():

javascript
// Only use this with content you trust!
element.setHTMLUnsafe(trustedContent, { sanitizer });

Parsing without inserting

You can also sanitize HTML without immediately inserting it:

javascript
const fragment = Document.parseHTML(untrustedHTML);
// Returns a sanitized DocumentFragment you can inspect or manipulate

Still Firefox-only for now, but it’s the kind of API that makes you realize how much weight we’ve all been carrying around by default.