HTML Entities Explained: When and Why to Escape Characters
What HTML entities are, which characters to escape, how encoding stops XSS, and how to encode or decode entities free in your browser.
The first time I broke a page with an unescaped <, I spent twenty minutes staring at a blank comment box before I noticed the browser had helpfully swallowed everything after if (x < 10). It read the < as the start of a tag and threw away the rest. That’s the whole reason HTML entities exist.
What an HTML entity actually is
Some characters mean something to the browser before they mean anything to a reader. < opens a tag. & starts an entity. " closes an attribute. When you want those characters to show up as plain text, you swap them for a code the browser prints literally.
There are three flavours:
- Named:
<,&,©— readable, but only a fixed set exists. - Decimal:
<,&— the character’s Unicode number. - Hex:
<,&— the same number in base 16.
All three render identically. < and < and < all draw a < on screen.
The five you can’t skip
For everyday HTML you really only need to worry about five characters:
&→&<→<>→>"→"'→'
Order matters here, and it trips people up. You escape the ampersand first. If you replace < with < and then go looking for stray & signs, you’ll re-encode the ampersand you just created and end up with &lt;, which prints the literal text < instead of a bracket. The HTML Entity Encoder does the ampersand pass first so you never hit that.
This is a security thing, not just a display thing
Escaping isn’t cosmetic. It’s the front line against cross-site scripting.
Say your site shows user comments. Someone types <script>fetch('/api/keys')</script> into the box. If you drop that straight into the page, the browser doesn’t see text — it sees a script tag, and it runs it in the next visitor’s session, with their cookies. Escape the < and > and that same input becomes inert text that reads <script>..., nothing more.
Modern frameworks like React and Vue escape output for you by default, which is why you rarely think about it. But the moment you touch innerHTML, build a string of HTML by hand, or write raw templates, that safety net is gone and escaping is back on you.
Decoding, and the non-ASCII trick
Decoding runs the other way: paste Fish & Chips — £5 and get back Fish & Chips — £5. Useful when you’re reading a scraped page, an RSS feed, or an API response that arrives pre-encoded and unreadable.
There’s also a checkbox to encode everything above plain ASCII — accented letters, Cyrillic, CJK, emoji — into numeric entities like 😀 for 😀. You won’t need it often. It earns its keep when a system chokes on anything that isn’t 7-bit ASCII, which still describes a surprising number of legacy email templates and older CMS fields.
One thing worth saying plainly: everything runs in your browser. Paste a config file or a customer comment full of markup and none of it leaves your machine.
Try it on your next stubborn snippet — the HTML Entity Encoder & Decoder encodes and decodes in the same box, instantly.