Turn HTML entity-encoded content into readable text by decoding common entities like & and < in seconds.
&, <, ©, decimal numerics like ' or ’, and hex numerics like & or —. Plain characters pass through unchanged.& becomes &, 😀 becomes š), and the field is marked Read Only to prevent accidental edits.& rendered as the literal text &), the input was encoded twice. Copy the output back into the input pane to run a second decode pass. Repeat until no &...; patterns remain.HTML entities exist because the <, >, &, ", and ' characters are reserved in HTML markup. Browsers, CMS template engines, sanitisers, RSS feeds, and scrapers escape them ā and sometimes re-escape them ā so that the source is safe to embed in a page. When you pull that source out of its rendering context, you want the literal characters back. The XConvert decoder unwinds named references, decimal numeric character references (&#NN;), and hex numeric references (&#xHH;) in one pass.
' shows up as ' and " shows up as " (or "). Decoding before you write to a database or CSV avoids double-escaped quotes breaking your INSERT statements.& instead of & was encoded twice somewhere in the pipeline ā usually a plugin escaping content the template engine already escaped. Running two decode passes confirms the diagnosis before you hunt the filter.<a href="...">). Decoding makes the inline links and tags legible without opening the message in a renderer.<script>alert(1)</script>) can be decoded to see exactly what would execute, without pasting into a browser address bar where the URL parser might fire it.’, “, ”, …, and —. Decoding shows the actual curly quotes (ā ā ā ⦠ā) so you can decide whether to keep them or normalise to ASCII.&amp; bugs.| Entity | Character | Unicode | Notes |
|---|---|---|---|
& |
& |
U+0026 | One of five HTML-mandatory escapes ā always encode inside attribute values |
< |
< |
U+003C | Mandatory in element content |
> |
> |
U+003E | Mandatory inside CDATA-like content; commonly escaped everywhere |
" |
" |
U+0022 | Mandatory inside double-quoted attribute values |
' |
' |
U+0027 | XML/HTML5 named entity; not defined in HTML4 ā use ' for max compatibility |
|
(no-break space) | U+00A0 | Prevents line wrap; not the same as ASCII space (U+0020) |
© |
Ā© | U+00A9 | Copyright sign |
® |
Ā® | U+00AE | Registered trademark |
™ |
⢠| U+2122 | Trademark |
… |
⦠| U+2026 | Horizontal ellipsis |
— |
ā | U+2014 | Em dash |
– |
ā | U+2013 | En dash |
’ |
ā | U+2019 | Right single quote (Word "smart apostrophe") |
“ / ” |
ā ā | U+201C / U+201D | Curly double quotes from Word/Pages |
The full WHATWG named-character reference table lists 2,125+ recognised names ā ⋢, ♥, and the rest of the long tail are handled automatically.
| Form | Pattern | Example | When you see it |
|---|---|---|---|
| Named | &name; |
& ā & |
Hand-written HTML, most templating engines, RSS feeds |
| Decimal numeric | &#NN; |
' ā ' |
XML output, JSON-embedded HTML, older HTML4 sanitisers (avoids the HTML4-undefined ') |
| Hex numeric | &#xHH; |
😀 ā š |
Modern serialisers, security tooling, anywhere astral-plane / emoji code points appear |
All three forms have been part of the HTML spec since HTML 2.0 (1995) ā every browser shipped in the last 25 years decodes them. The XConvert decoder treats them interchangeably.
& and ' instead of & and '?The page you scraped served pre-escaped HTML so the characters wouldn't be misinterpreted as markup or quote terminators. Browsers decode these automatically before display, but tools like requests.get(url).text in Python, fetch(url).text() in JavaScript, or curl give you the raw source ā entities and all. Run the text through a decoder (or call html.unescape() in Python, or use an HTML parser like BeautifulSoup with .get_text() which auto-decodes) before storing it.
Yes ā the decoder is pure string substitution running in your browser tab. It produces text, not a live DOM, so a decoded <script> tag does not execute. The output pane is a read-only <textarea> that displays the characters literally. That said, do not then paste the decoded result into an HTML page's innerHTML or a templating engine without re-escaping ā that's exactly the XSS path the encoding was preventing.
&#NN;, &#xHH;) supported everywhere?Yes. Decimal and hex numeric character references have been in the HTML spec since the earliest versions and every shipping browser handles them. They cover the full Unicode range ā 💩 produces š©, 😀 produces š ā without needing the named-entity table. If you're emitting HTML and worried about old-CMS compatibility, numeric references are the safest choice.
and a regular space? decodes to U+00A0 (no-break space). It renders the same width as a normal space, but it tells the layout engine "do not break the line here" ā useful for keeping a number with its unit ("10 kg") or a name with its title ("Dr. Smith"). After decoding, the character is a regular character in your text but is not equal to U+0020 ā string comparisons (str == "10 kg") and .split(' ') calls will silently fail. Normalise with a regex like s/[Ā \s]+/ /g if you need plain spaces.
’, “, and … keep showing up in content pasted from Word?Microsoft Word and Pages auto-correct straight ASCII quotes/dashes into typographic ("smart") variants: ' ā ā (U+2019), " ā ā ā (U+201C/201D), ... ā ⦠(U+2026), -- ā ā (U+2014). When that text round-trips through an HTML editor that escapes non-ASCII characters, you see the entity names instead of the glyphs. Decoding reveals the actual curly characters; if you want plain ASCII, run a follow-up replace step (ā ā ', etc.).
Yes, using the "textarea trick" ā the browser's own HTML parser decodes entities when you assign to innerHTML:
function decodeEntities(s) {
const t = document.createElement('textarea');
t.innerHTML = s;
return t.value;
}
Setting innerHTML on a <textarea> (rather than a <div>) is the safe variant: the textarea will not execute <script> tags or fire image onerror handlers contained in the input ā they become inert text inside the textarea's value. On the server side or in modern frontend code, the he library is the standard choice; in Python, html.unescape() from the standard library; in PHP, html_entity_decode($s, ENT_QUOTES | ENT_HTML5, 'UTF-8').
&amp; ā why?The text was HTML-encoded twice. Somewhere in the pipeline, content that already contained & (the encoded form of &) was treated as if it were raw text and encoded again: the & in & became &, producing &amp;. One decode pass gives you &; a second pass gives you &. Find the duplicated escape call ā common culprits are a CMS plugin escaping content the template engine has already escaped, or a JSON-in-HTML serialiser that double-encodes before injecting into a data- attribute.
Anything that doesn't match a known named reference or a valid numeric pattern is left in the output unchanged ā so ¬arealentity; stays as ¬arealentity;, and a stray ampersand like Q&A (no semicolon, no defined name) stays as Q&A. This makes broken entities visible at a glance instead of silently dropping characters. The HTML5 parser is somewhat more lenient with missing semicolons for legacy named entities (e.g. & without ; may still be recognised in attribute context); the XConvert decoder follows the strict-with-semicolon form to avoid surprising you.
Yes ā use the HTML Entity Encoder for the reverse direction. Together they cover round-trip workflows. For related encoding tasks, see URL Decoder for %XX percent-encoded URLs and Base64 Decoder/Encoder for ==-padded base64 strings. If you're cleaning HTML output for downstream text pipelines, HTML to Markdown strips the tags entirely and decodes entities in one step.