A small whitelist-based HTML sanitizer for user-submitted rich text. Strips <script>, <style>, <iframe>, event-handler attributes, and unsafe URL schemes (javascript:, data:, etc.). Used by <k-chat> on every message it accepts, but works as a standalone util for any place you accept HTML from a contenteditable or rich-text editor.
import sanitizeHtml from './utils/sanitizeHtml.js';
const dirty = '<p>Hello <script>alert("xss")</script><b>world</b></p>';
const clean = sanitizeHtml(dirty);
// → '<p>Hello <b>world</b></p>'
sanitizeHtml(html, options?)html: stringUntrusted HTML to sanitize. null, undefined, and non-strings are coerced to "".
options: Object (optional)allowedTags — Set<string> of UPPERCASE tag names (e.g. "B", "P"). Overrides the default whitelist.allowedAttrs — Set<string> of attribute names allowed on every tag.allowedAttrsPerTag — { TAGNAME: Set<string> } map of attributes allowed per specific tag.stringThe sanitized HTML. Disallowed elements are replaced by their (sanitized) children so user text is preserved; <script>, <style>, and similar are removed entirely (children too).
A, B, STRONG, I, EM, U, S, STRIKE, BR, P, DIV, SPAN, UL, OL, LI, BLOCKQUOTE, CODE, PRE, H1–H6
SCRIPT, STYLE, IFRAME, OBJECT, EMBED, LINK, META, BASE, FRAME, FRAMESET, NOSCRIPT, SVG, MATH
class, plus any data-*<a>: href, title, target, relhref and src values are checked against a safe-scheme regex; anything that doesn't match http(s):, mailto:, tel:, a relative path, or a fragment is removed. Links with target="_blank" automatically get rel="noopener noreferrer" to prevent reverse-tabnabbing.
Pass an options object to tighten or loosen the defaults:
const html = sanitizeHtml(userInput, {
allowedTags: new Set(['B', 'I', 'EM', 'STRONG', 'A', 'BR', 'P']),
allowedAttrsPerTag: {
A: new Set(['href'])
}
});
This util only protects content that flows through your client code. If your app accepts user-submitted HTML and stores or echoes it to other users, the server must independently sanitize before storing and again before sending it back. Battle-tested server libraries: DOMPurify (Node), sanitize-html (Node), Bleach (Python), sanitize (Ruby).