Escape HTML entities

Escape or unescape HTML entities (replace characters like <,>, &, " and \' with their HTML version)

HTML Entities Encoder & Decoder: Character Reference Standards, Unicode Mappings & XSS Mitigation

1. Overview & Core Advantages

HTML Entities are standardized textual representations used in SGML, XML, and HTML documents to encode reserved markup syntax, control characters, and non-ASCII glyphs. Web browsers interpret symbols such as < and > as element tag delimiters. When such characters must be rendered literally as text content rather than executed as DOM markup, they must be converted into their respective entity representations—such as &lt; and &gt;.

In modern web development and software security architectures, handling HTML entities correctly is paramount. Misconfigured character decoding or omitted escaping directly exposes web applications to Cross-Site Scripting (XSS) vulnerabilities, HTML injection attacks, and document rendering corruptions across diverse international character encodings.

Core Architectural Advantages

  • 100% Client-Side Local Transformation: All entity conversions, lookups, and regex parsing execute directly in the client browser JavaScript runtime.
  • Zero External Telemetry & Total Privacy: Proprietary strings, customer database records, and confidential user input never cross external networks or remote APIs.
  • W3C & WHATWG Standards Compliance: Operates in strict adherence to the HTML5 Named Character References specification and Unicode Standard (ISO/IEC 10646).
  • Zero Network Latency: Instantaneous transformations with immediate bidirectional clipboard copy support.

2. Technical Architecture & Algorithmic Principles

Entity Anatomy: Named References vs. Numeric Character References (NCR)

An HTML entity can be formulated in three distinct syntactical formats:

  1. Named Character References: Human-readable mnemonics defined in the W3C HTML5 specification (which contains over 2,231 standard named character references).
    • Format: &name;
    • Example: &amp; (&), &quot; ("), &copy; (©).
  2. Decimal Numeric Character References (NCR): Specifies the character’s direct Unicode code point value in base-10 format.
    • Format: &#DDDD;
    • Example: &#60; (<), &#169; (©).
  3. Hexadecimal Numeric Character References (NCR): Specifies the character’s direct Unicode code point in base-16 format (case-insensitive in HTML5).
    • Format: &#xHHHH;
    • Example: &#x3C; (<), &#xA9; (©).

Reserved Characters in HTML Parsing

According to the W3C HTML parsing specification, five characters represent fundamental syntax tokens and must always be escaped in text nodes or attribute contexts:

Character Literal Meaning Named Entity Decimal NCR Hexadecimal NCR Contextual Risk
& Ampersand &amp; &#38; &#x26; Triggers entity parsing; causes ambiguous entity errors
< Less Than &lt; &#60; &#x3C; Initiates tag start token; allows script injection
> Greater Than &gt; &#62; &#x3E; Closes HTML tags
" Double Quote &quot; &#34; &#x22; Breaks double-quoted HTML attributes (value="...")
' Single Quote &#39; / &apos; &#39; &#x27; Breaks single-quoted HTML attributes (value='...')

Note on &apos;: While valid in XML and modern HTML5, &apos; was historically omitted from the official HTML 4.01 specification, leading security-conscious sanitization engines to standardize on decimal &#39; for universal legacy browser compatibility.

State-Machine Tokenization & Parsing Algorithms

When a browser parses an HTML stream, encounter with the ampersand byte (0x26) transitions the internal tokenizer into the Character Reference State:

  1. If followed by # (0x23), the parser switches to the Numeric Character Reference State.
    • If subsequent character is x or X, it enters the Hexadecimal NCR State, consuming hexadecimal digits until a terminating semicolon ; is reached.
    • Otherwise, it consumes decimal digits in the Decimal NCR State.
  2. If followed by an ASCII alphanumeric character, it enters the Named Character Reference State, performing a longest-prefix search against the internal WHATWG entity table.
  3. If no matching entity is found or syntax is invalid, the parser emits a parse error and treats the ampersand as a literal text character.

3. Step-by-Step Configuration & Implementation Guide

3.1 Browser-Native Escaping vs. Lodash / He Library Implementation

Different runtime environments provide various mechanisms for encoding and decoding HTML entities:

// Approach 1: Lightweight Lodash-compatible regex escaping (Core 5 characters)
const HTML_ESCAPES: Record<string, string> = {
  '&': '&amp;',
  '<': '&lt;',
  '>': '&gt;',
  '"': '&quot;',
  "'": '&#39;',
};

const HTML_UNESCAPES: Record<string, string> = {
  '&amp;': '&',
  '&lt;': '<',
  '&gt;': '>',
  '&quot;': '"',
  '&#39;': "'",
  '&apos;': "'",
};

export function escapeHtml(str: string): string {
  return str.replace(/[&<>"']/g, (char) => HTML_ESCAPES[char]);
}

export function unescapeHtml(str: string): string {
  return str.replace(/&(?:amp|lt|gt|quot|#39|apos);/g, (entity) => HTML_UNESCAPES[entity]);
}

3.2 Full Unicode & Comprehensive Entity Decoding using the DOM

In client-side browser contexts, you can leverage native DOM parsing engines for comprehensive W3C entity decoding without loading bulky lookup tables:

export function decodeHtmlEntitiesDOM(input: string): string {
  const doc = new DOMParser().parseFromString(input, 'text/html');
  return doc.documentElement.textContent || '';
}

// Example usage:
console.log(decodeHtmlEntitiesDOM('&copy; 2026 &mdash; Ac&ccedil;ent &amp; Co.'));
// Output: "© 2026 — Accent & Co."

3.3 Safe Server-Side Escaping in Node.js (Preventing ReDoS)

In backend environments lacking a DOM window, avoid naive unvalidated regex iterations on untrusted user strings. Use compiled lookup trees or deterministic streaming tokenizers:

import { encode, decode } from 'html-entities';

// Production sanitization with explicit mode configuration
const rawComment = '<script>alert("xss")</script> & "café"';
const safeOutput = encode(rawComment, { mode: 'specialChars', level: 'html5' });
console.log(safeOutput);
// Output: "&lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt; &amp; &quot;café&quot;"

4. Production Engineering & Security Architecture (XSS Defense)

The Role of Contextual Encoding in Application Security

A critical vulnerability in web applications is relying on generic HTML entity escaping in non-HTML contexts:

+-------------------------------------------------------------+
|               Untrusted User Input Payload                  |
+------------------------------+------------------------------+
                               |
       +-----------------------+-----------------------+
       |                       |                       |
       v                       v                       v
[HTML Body Context]     [Attribute Context]     [Script Context]
<div>{{ userInput }}</div>  <input value="{{...}}">  <script>var x = '{{...}}';</script>
Safe with HTML Entities  Safe with Attribute Esc  FATAL: Entities decoded inside JS!
(e.g., &lt;script&gt;)   (Escape " and ')        (Allows direct script execution)
  1. HTML Body Context (<div>, <p>): Escaping &, <, >, ", ' effectively neutralizes tag injection.
  2. HTML Attribute Context (<input value="...">): Double and single quotes must be rigorously escaped. Additionally, URI attributes (href, src) must be validated against javascript: pseudo-protocols before entity encoding.
  3. JavaScript Execution Context (<script>): HTML entity encoding provides ZERO security inside a <script> tag. The JavaScript engine parses string literals independently of HTML entities. Inside script blocks, JSON serialization with Unicode escaping (\u003C) or strict CSP (Content Security Policy) is mandatory.

Content Security Policy (CSP) Integration

Pairing deterministic client-side entity escaping with strict CSP response headers delivers defense-in-depth:

Content-Security-Policy: default-src 'self'; script-src 'self'; object-src 'none';

5. Frequently Asked Questions (FAQs)

Q1: What happens if I double-encode a string containing existing HTML entities?

Double-encoding occurs when an already-escaped string (such as &lt;div&gt;) is processed through an entity encoder a second time. The leading ampersand & is converted to &amp;, resulting in &amp;lt;div&amp;gt;. When rendered in the browser, the user sees raw code &lt;div&gt; on screen rather than formatted content. Sanitization pipelines must maintain clear boundaries regarding data states.

Q2: Why is &apos; sometimes avoided in favor of &#39;?

While &apos; was defined in XML and XHTML, it was originally excluded from the legacy HTML 4.01 standard. Ancient browsers (such as Internet Explorer 8 and earlier) would fail to parse &apos;, rendering literal unparsed entity strings. The decimal numeric character reference &#39; is universally parsed by every browser generation and standard.

Q3: Should UTF-8 characters like emojis (e.g., 😊) be converted to HTML entities?

In modern web architectures utilizing <meta charset="UTF-8">, converting non-ASCII Unicode characters, foreign alphabets, or emojis to numeric HTML entities is unnecessary. UTF-8 natively supports the entire Unicode code space. Only syntax-critical delimiters (<, >, &, ", ') should be escaped to optimize bandwidth and maintain clean database indexes.

Q4: Does HTML entity encoding protect against SQL Injection?

No. HTML entity encoding is strictly designed for browser rendering and HTML parser semantics. SQL injection occurs at the database query parser layer. Protection against SQL injection requires parameterized queries (prepared statements) and ORM abstractions, not HTML entity escaping.


6. Client-Side Privacy & Security Guarantee

All HTML entity encoding and decoding operations within this tool are executed 100% locally in your web browser. No text fragments, proprietary markup, or payload data are transmitted across network sockets or recorded in telemetry backends.