HTML Entity Decoder
Turn é back into é, or escape text so HTML stops eating it.
Free, no signup, no limits
Café & Bar — open tíl 11 Price: 5€ or £4.50, that’s ½ of last year Tags: <strong>new</strong>, été, — and spacing
How to decode HTML entities
Paste the text on the left. Named, decimal and hex references all resolve in a single pass and the plain text appears on the right.
The other direction escapes text so HTML stops interpreting it, which is what you want before dropping a snippet into a page or a template.
Why text arrives full of &
Because it was encoded twice.
A CMS escapes the text on the way into the database, then a template escapes it
again on the way out. The ampersand of the first entity is itself a character
that needs escaping, so é becomes &eacute; and what the reader
sees is the entity, printed literally, in the middle of a sentence.
Decoding once here gives back the single-encoded version. Run that through again and you have the text. If you find yourself doing it three times, the bug is in the pipeline rather than in the content, and it will keep happening.
Only five characters actually need encoding
The ampersand, the two angle brackets, and both quote marks. Nothing else is required for HTML to parse correctly, and that is what the encode direction does by default.
Encoding every accented letter as well is a habit left over from Latin-1 pages,
when a byte above 127 genuinely could not be trusted to survive. On a UTF-8
document, which is every document now, an e acute is perfectly safe as itself,
and turning it into é only makes the source harder to read and diff.
The switch is there for the case where the destination really cannot take UTF-8: an old CMS field, an export format, a system nobody will let you touch.
Unknown entities are left alone
&foo; comes back as &foo;.
It is far more likely to be literal text than a broken entity, and a tool that quietly deletes anything shaped like an entity loses data in a way you cannot detect afterwards. The same applies to a numeric reference out of Unicode's range: it is text, so it stays text.
Why this does not use innerHTML
Because the usual snippet for decoding entities is to assign the string to a
detached element's innerHTML and read textContent back. It is three lines,
it is the top answer on every search, and it hands attacker-controlled text
straight to the HTML parser.
The parser resolves <img src=x onerror=...> into a real node, and a detached
element is one careless appendChild away from firing it. Nothing here should
be able to do that, so decoding is a lookup table, which can only ever return a
character.
What else might be in that text
Text that arrived through a CMS usually carries more than entities. Non-breaking spaces, curly quotes and the odd zero-width character all survive the round trip and none of them are visible.
The AI text cleaner strips those in one pass, and the
URL encoder handles the other escaping scheme, the
%20 one, which people mix up with this constantly.
Everything runs in your browser. Nothing is uploaded.
Frequently asked questions
More Text tools
Everything else in the Text toolbox.
Something missing here?
If this tool almost does what you need, say what is missing. That is usually how the next version gets built.