HTML Entity Encoder and Decoder

Escape text for HTML, or decode entities back. Only five characters need escaping in a UTF-8 document, and the context you are inserting into decides whether those five are anywhere near enough.

Paste below, or drop a file anywhere on this panel

Or drop a file anywhere on this panel. Nothing is uploaded: the analysis runs in this tab.

The answer appears here

Paste on the left and press Convert. Nothing leaves this tab.

Examples

Real input you can load into the tool above. Each one shows a different thing going wrong, because that is what the tool is for.

An entity missing its semicolon

Browsers accept it and strict XML parsers do not, which is a sanitiser bypass

a &amp b

Escaped twice

& shows as a literal ampersand on the page, from a template escaping an already-escaped value

<script>

Common mistakes

These are the ones that fail silently. The config is accepted, nothing raises an error, and the consequence arrives later.

  1. Replacing the ampersand last

    Escaping < to &lt; and then escaping & turns it into &amp;lt;. Any input without an ampersand looks correct, which is most test input, so this ships.

    Instead:Replace & first, then the other four.

  2. Converting every non-ASCII character to a named entity

    That was a workaround for legacy document encodings. In UTF-8 it makes the markup larger, harder to read and harder to search, and buys nothing.

    Instead:Escape the five that matter, declare UTF-8, and write everything else as itself.

  3. Treating HTML escaping as universal

    The five escapes are safe for element content and quoted attributes only. Inside a script block, inside CSS, or in an href where a javascript: scheme is the risk, they do nothing. This is the classic XSS.

    Instead:Escape for the context. Use a template engine that tracks context rather than escaping by hand.

Five characters need escaping, and the context decides whether that is enough

Escaping for HTML is not a general character-encoding problem. It is about the characters that can end an attribute or open a tag, and there are five of them.

The five, and the order they must be replaced in

Ampersand, less than, greater than, double quote and apostrophe. The ampersand has to be replaced FIRST, or the entities produced by the other four get escaped again and you emit &amp;lt; where you meant &lt;. An implementation that replaces in the wrong order looks correct on any input without an ampersand, which is most test input.

Everything else is a legacy workaround

Named entities for accented and symbol characters existed because documents were in a legacy encoding. In a UTF-8 document an accented character is just itself. Converting it to a named entity makes the markup larger, harder to read and harder to search, for no benefit at all. Declare UTF-8 and write characters as themselves.

The missing semicolon is a real parser disagreement

Browsers accept many named entities without the closing semicolon for backwards compatibility. Strict XML parsers do not. So the same markup means different things to a browser and to an XML toolchain, and a sanitiser that disagrees with the browser about where an entity ends is a filter bypass rather than a formatting nit. Always write the semicolon.

Escaping is context-dependent, and this is where XSS lives

These five escapes make text safe as element content and as a quoted attribute value. They do NOT make it safe inside a script block, inside CSS, or in an href where a javascript: scheme is the risk. Each needs its own escaping, and applying HTML escaping to a JavaScript string literal is the classic mistake. Prefer a template engine that knows the context over escaping by hand.

Double escaping

A visible &amp; on the page means a value was escaped twice: usually once by a template that does it automatically and once by hand. Store the raw value and escape exactly once, at the point of output.

What this cannot see

The context you are inserting into, which is what decides whether escaping is sufficient, and whether the input is trusted. It converts the text you paste, in your browser, and uploads nothing.