HTML Escape and Unescape Tool
Escape HTML for text or quoted attributes, decode nested character references locally, and flag unresolved, markup, or script-shaped output.{{ outputText }}
| # | Input token | Output token | Kind | Pass | Status | Copy |
|---|---|---|---|---|---|---|
| {{ row.position }} | {{ row.input }} | {{ row.output }} | {{ row.kind }} | {{ row.pass }} | {{ row.status }} |
| Check | Status | What to review | Copy |
|---|---|---|---|
| {{ row.check }} | {{ row.status }} | {{ row.detail }} |
Browsers decide whether characters are text or markup from their location in an HTML document. A less-than sign can begin a tag, an ampersand can begin a character reference, and a matching quote can end an attribute value. Escaping replaces those characters with references such as <, &, or " so the intended characters can be represented without taking on those structural roles.
The required escapes depend on the insertion context. Text placed between ordinary tags needs different treatment from text placed inside a quoted attribute. XML recognizes only five predefined named references, while HTML recognizes a much larger named set. Decimal and hexadecimal numeric references offer alternate spellings for a Unicode code point.
- In an HTML text node, ampersand, less-than, and greater-than characters are the main replacements in this conversion profile.
- In a double-quoted attribute, the double quote must also be escaped; in a single-quoted attribute, the apostrophe must be escaped.
- A profile that escapes both quote types is suitable only for quoted ordinary HTML attributes. It does not make unquoted attributes, event-handler attributes, CSS, JavaScript, or URL schemes safe.
- Unescaping reverses recognized references into characters. If those characters form tags or script-shaped text, inserting the result as HTML can activate behavior that was inert while escaped.
Nested references arise when escaped text is escaped again. For example, &lt; becomes < after one decode pass and < after a second. Multiple passes can be necessary for intentional nesting, but they can also expose markup sooner than expected. Decode only as far as the receiving context requires.
Escaping is context-specific output encoding, not HTML sanitization. It can preserve untrusted text for display when the correct context is known. It does not remove unsafe elements, attributes, protocols, or scripts from HTML that is meant to remain markup. Sanitization and a safe insertion method are separate requirements.
How to Use This Tool:
Pin the direction whenever the source may legitimately contain both raw characters and references. Then choose the destination context for escaping or the parsing policy for unescaping.
- Paste HTML or text, or load one TXT, HTML, XML, or SVG file up to 1 MiB. The text input accepts up to 120,000 Unicode characters.
- Choose Escape source or Unescape references. Auto detect selects unescape when it finds reference-shaped text and escape otherwise, so pinning the direction is safer for mixed or literal examples.
- For escaping, select Escape context to match the eventual insertion point. For unescaping, choose tolerant HTML handling or strict semicolons and set 1 to 6 decode passes.
Use one decode pass for initial inspection. Increase the count only when the output is intentionally nested, and stop when markup or the intended literal text appears.
- Read Copy safety before using the result. Unresolved references, decoded markup, script-shaped output, or a failed round trip require a manual context check; none of those checks sanitizes the text.
Interpreting Results:
The converted text is the complete transformation. The ledger explains each changed or unresolved token and records the decode pass that handled it. A reference marked for review remained unchanged because its name was unsupported or ambiguous, or because strict handling required a missing semicolon.
A passing round trip means the inverse transform restored the prepared source under neutral settings. Normalization, trimming, line-break conversion, nested decoding, or a different escape context can make the comparison fail without implying a parser error.
Markup and script signals are warnings based on recognizable text patterns. Zero signals do not certify safety, and one signal does not prove malicious intent. If unescaped output will be inserted as HTML, use an appropriate sanitizer and a safe DOM insertion method rather than relying on the signal count.
Technical Details:
HTML character references may be named, decimal numeric, or hexadecimal numeric. Named references draw from the HTML reference table. Numeric references identify a code point, while invalid scalar values are replaced with the Unicode replacement character. Certain numeric values in the range historically associated with Windows-1252 are remapped according to HTML parsing behavior.
Transformation Core:
| Profile | Required mappings | Important limit |
|---|---|---|
| HTML text node | & to &, < to <, and > to > |
Quote characters remain literal. |
| Double-quoted attribute | Text-node mappings plus " to " |
The attribute must actually be double quoted. |
| Single-quoted attribute | Text-node mappings plus ' to ' |
The attribute must actually be single quoted. |
| Any quoted HTML attribute | Text-node mappings plus both quote characters | This does not validate attribute names, URLs, CSS, or event-handler content. |
| XML five references | &, <, >, ", and ' |
No additional HTML named-symbol mapping is implied. |
| Decimal or hexadecimal | The same five reserved characters use numeric references such as & or &. |
Other characters remain literal in these profiles. |
| Common named symbols | The reserved mappings plus a focused set such as copyright, currency, dashes, quotation marks, and mathematical symbols | It is not an exhaustive rewrite of every character to a named reference. |
On escape, the selected profile is applied one Unicode character at a time. Carriage returns are discarded. Line feeds are preserved, converted to <br> followed by a line feed, or represented as . Optional NFC or NFKC normalization runs after conversion, and trimming removes whitespace only from the two outer ends.
Rule Core for unescaping:
| Input form | Tolerant HTML handling | Strict handling |
|---|---|---|
| Named reference with semicolon | Decode when the name is recognized. | Decode when the name is recognized. |
| Named reference without semicolon | Decode only a supported legacy no-semicolon name; leave other names for review. | Leave unchanged for review. |
| Numeric reference | Decode decimal or hexadecimal form with or without a semicolon. | Require the semicolon. |
| Unsupported or ambiguous name | Preserve the original token. | Preserve the original token. |
| Nested reference | Repeat for up to 1 to 6 passes and stop early when a pass makes no change. | |
Auto detection resolves to unescape when the source contains a named or numeric reference-shaped token; otherwise it resolves to escape. This is a syntactic decision. A literal tutorial example containing & may therefore need the operation pinned to avoid an unintended direction.
Privacy and Safety Notes:
Pasted text and selected file content are converted in the browser. No server-side processing is required for the transformation.
- Escaped output is only appropriate for the context represented by the selected profile. JavaScript, CSS, URL, unquoted-attribute, and HTML-comment contexts need different defenses.
- Unescaped output may contain active markup, event handlers, dangerous URL schemes, or elements that a pattern check misses. Treat it as text unless trusted HTML has been sanitized.
- Unicode normalization and repeated decoding can change exact characters or reveal another encoded stage. Preserve the source for comparison.
Worked Examples:
Text node versus quoted attribute
The text Coffee & "tea" becomes Coffee & "tea" in the text-node profile because quotes do not delimit ordinary text there. In a double-quoted attribute, the same source also changes the double quotes to " so they cannot end the attribute value.
Two-pass nested reference
The source &lt;strong&gt; becomes <strong> after one pass and <strong> after two. The second result is markup-shaped text, so the safety review flags it and it should not be inserted as live HTML without an explicit trust and sanitization decision.