HTML Entity Encoder / Decoder
Convert between special characters and & < and other HTML entities
HTML entity encode and decode: when escaping is mandatory and when it is not
What encoding and decoding do
Encoding replaces the five characters that carry syntactic meaning with entities. These five are the entire "must escape" set:
| Character | Entity | Why it must be escaped |
|---|---|---|
& | & | Start of an entity; unescaped, the following sequence is misparsed |
< | < | Start of a tag; unescaped, it breaks document structure |
> | > | End of a tag (often optional alone, but recommended alongside the others) |
" | " | Attribute value delimiter |
' | ' | Attribute values may also be delimited by single quotes |
Decoding is the reverse: it restores the entity form back to a character. Besides those five, it also handles named entities (such as © —) and numeric entities (decimal ©, hexadecimal ©, both the copyright sign). Decoding relies on the browser's own parser, so its entity support matches the browser — more reliable than maintaining your own entity table.
When escaping is mandatory
The only test that matters is this: will this text be placed into HTML as content or as an attribute value?
- Displaying user input on a page — must escape, or it is an XSS hole. A user submitting
<script>alert(1)</script>would otherwise be executed by the browser as script. - Concatenating data into an HTML string (server-side template concatenation, front-end string concatenation) — must escape. A single
&in a product name a user typed can scramble the page structure. - Showing a code snippet as text — must escape. To display
<div>as characters rather than render an element, write it as<div>(the manual trick used by many documentation sites).
When escaping is unnecessary — and why it is still misused
| Context | Needed? | Note |
|---|---|---|
| Inside a JSON string | No | JSON has its own escaping (\" \\); HTML entities there are a type error |
| URL parameter | No | Use percent-encoding (%26), not & |
| Plain text file, log | No | No HTML parsing; escaping only makes content unreadable |
| Database storage | No | Store the original; escape on output. This matters — see below |
| CSV cell | No | CSV has its own quoting rules |
The fourth row is the key point: do not "escape on insert into the database". It looks safe but causes three kinds of trouble:
- Double escaping. Escape once on insert and again on output, and the user sees raw entities like
&lt;. - Data becomes irreversible. You stored
&, so you can no longer tell whether the user originally typed&or&— two different inputs collapse into one stored value. - Non-HTML uses get polluted. The same data exported to CSV, sent to an API, or written into email all carry HTML entities.
The correct principle is "store the original, escape per output context". This is also the default behaviour of modern template engines (auto-escaping), so with a framework you usually do nothing — and manually "adding a layer of escaping" is a common source of bugs.
Symptom-to-cause table
| What you see | Cause | Fix |
|---|---|---|
<div> shown on the page | Escaped twice, or one extra layer | Find the duplicated escaping step and remove one |
Page shows & | Stored &, or escaped on insert | Clean the stored data; stop escaping on insert |
& inside JSON | Used HTML entity instead of JSON escaping | Use a JSON escaping tool instead |
Copied content carries | Entity came along when copying from a web page | Decode once; note (U+00A0) is not the same character as a normal space |
The last row hides a detail worth remembering: a non-breaking space (U+00A0) is not a normal space. It looks identical, but it causes "looks fine, yet it is wrong" failures in string comparison, in regex \s (which some implementations do not match), and when pasted into code. Replacing it with a normal space via the whitespace cleaner is a common fix.
How to use the tool
The encode button processes the five mandatory-escape characters listed above; the decode button restores those five entity forms plus named and numeric ones. Both directions run inside the page; nothing is sent to a server.
FAQ
Does encoding handle all characters?
It escapes the five characters with special meaning in HTML: & < > " '. Others are kept as-is to avoid breaking rendering.
Does decoding support numeric entities?
Yes. Decoding uses the browser parser, so decimal/hex entities like { and named entities are correctly restored.