DevKitHub

Encoding & Conversion

HTML Entity Encoder and Decoder

Convert characters to HTML entities or back again. The default escapes the five characters that change how a parser reads a document, which is the correct set for HTML.

1 line
1 line

Escaping is context-dependent. These entities are correct for HTML text and attribute values, and do nothing inside a script block, a URL or a CSS value — each of which needs its own escaping.

This tool runs entirely in your browser. Your input is never uploaded, stored or logged.

How it works

The default mode escapes five characters and nothing else: ampersand, less-than, greater-than, double quote and apostrophe. That is not minimalism, it is the correct answer — those five are what can change the structure of a document or break out of an attribute, and escaping more adds noise without adding safety. The ampersand has to be escaped first, before the others are introduced, or the entities produced by the later replacements get escaped a second time and you end up with < where you wanted <.

Named and numeric modes go further and escape every non-ASCII character, which is useful for a document that has to survive a pipeline with uncertain encoding. Named mode uses the HTML name where one exists — ©, —, é — and falls back to a numeric reference otherwise, because HTML5 defines over two thousand names and only a fraction appear in real documents. Characters outside the Basic Multilingual Plane, emoji among them, are escaped by code point rather than by their two UTF-16 halves; escaping the halves separately produces a pair of references that no parser will accept.

Worth being clear about what escaping does not do. It is context-dependent: the same string needs different treatment in HTML text, in an attribute, inside a script block, in a URL and in a CSS value, and HTML escaping in the last three protects nothing at all. Escaping on the way into storage rather than on the way out to a page is the other common mistake, because the stored value is then wrong for every other consumer.

Common problems

Every example below is run against this tool in our test suite, so what it says here is what the tool actually does.

The output shows < instead of <.

Why:
The text was escaped twice. Each pass escapes the ampersands the previous pass introduced, so < becomes < and then <.
Fix:
Escape once, at the point of output. If a template engine already escapes — most do by default — do not escape before handing it the value.

Escaped output still produced a working script injection.

Why:
HTML escaping is the wrong escaping for the context. Inside a script block, an event handler attribute, a URL or a CSS value, the five HTML characters are not what breaks out, so escaping them changes nothing.
Fix:
Escape for the context you are writing into, and prefer an API that cannot be confused — textContent over innerHTML, a parameterised URL over string concatenation.

An emoji turned into two broken references.

Why:
Characters above U+FFFF are stored as two UTF-16 halves in JavaScript. Escaping character by character with .charCodeAt produces two references for the surrogate halves, which is not valid.
Fix:
Escape by code point. This tool does, which is why 🚀 becomes the single reference 🚀.

Frequently asked questions

Which characters actually need escaping in HTML?
In element text, & and <. In an attribute value, also the quote character that delimits it. Escaping all five — & < > " and ’ — is the conventional safe set and what this tool does by default.
Does escaping HTML prevent XSS?
Only in HTML text and attribute contexts, and only when done at output time. It does nothing inside a script block, a URL or a CSS value, each of which needs its own escaping. Escaping is one layer, not the answer.
What is the difference between named and numeric entities?
They are interchangeable. &copy; and &#169; produce the same character. Named entities are more readable, numeric ones always work because they need no lookup table, and only the five required names are guaranteed to be understood by an XML parser.
Why does my &nbsp; look like a normal space?
It is a non-breaking space — a real character that renders like a space but prevents a line break and is not collapsed by HTML whitespace rules. It is a frequent cause of text that fails to match in a comparison or a search.

Read more about this

Last updated