HTML Entity Encoder and Decoder
Escape the characters that would otherwise be read as markup, or decode a string that arrived full of & and ’. Emoji and other characters above U+FFFF come out as one entity rather than two broken halves.
The first option escapes five characters and leaves your accents and dashes as real text, which is what you want on a UTF-8 page.
Only used when there is no named entity for the character. Both are understood everywhere.
Three ways to write the same character
An entity reference is a way of writing a character using only plain ASCII. There are three forms and browsers treat them identically: named (&), decimal (&) and hexadecimal (&). All three produce an ampersand. Named references are readable; numeric ones always exist, even for characters nobody bothered to name.
You only actually need five
On a page declaring <meta charset="utf-8">, you can type an em dash, an accented letter or an emoji directly into the source and it will render. What you cannot type directly is anything the parser would read as markup:
&— always, everywhere. An unescaped ampersand followed by letters can be swallowed as an entity, soTom & Jerryis not optional pedantry.<— always in text content. It is what starts a tag.>— by convention rather than necessity, but escaping it costs nothing and avoids surprises in edge cases."and'— inside attribute values, whichever one you used as the quote. Escaping both means you never have to think about which.
Escape those five and text is safe in HTML text nodes and quoted attributes. That is what the first mode above does. The other two modes exist for the times you cannot trust the encoding of every system a file will pass through.
Why the apostrophe comes out as a number
This tool writes ' rather than '. The named form is defined in XML and in HTML5, but it was not part of HTML 4, so older parsers and a surprising number of email clients render it as the literal text '. The numeric reference has always worked. It is four characters longer and one less thing to debug.
Escaping is not sanitising, and context decides everything
The five-character escape is correct for HTML text and for quoted attribute values. It is not correct, and not safe, everywhere else:
- Unquoted attributes.
<div class=VALUE>ends at the first space, so escaping quotes buys you nothing. Quote your attributes. - Inside
<script>. That is a JavaScript string context. Entity references are not decoded there, and the sequence</script>inside a string will still end the block. - Inside a URL attribute. Entities are decoded before the URL is parsed, so
javascript:alert(1)survives entity escaping intact and becomes ajavascript:link. Validate the scheme; do not rely on escaping. - Inside CSS. Different escaping rules again.
And escaping is not stripping. This tool makes markup display as text. It does not remove anything dangerous, because it does not need to — nothing survives as markup. If you want to keep some tags and drop others, that is sanitising, and it needs a parser with an allowlist.
Emoji, surrogate pairs and the broken output you have seen
Characters above U+FFFF — emoji, rare CJK, most historic scripts — are stored in JavaScript as two code units. An escaper that walks a string one index at a time emits two useless references like ��, which no parser can reassemble into the original character. This tool iterates by code point, so a grinning face becomes the single reference 😀.
What the decoder will and will not do
Decoding here uses the browser's own HTML parser, which means it follows HTML5's rules — including the legacy ones. HTML5 decodes a list of around a hundred older entities even without the closing semicolon, so © becomes a copyright sign. An XML parser would reject that outright. If you are round-tripping content through RSS, SVG or an XML config file, remember that XML defines exactly five named entities — amp, lt, gt, quot and apos — and everything else has to be numeric.
Two more limits worth knowing. Unrecognised references pass through unchanged rather than raising an error, exactly as a browser would render them, so a typo in an entity name is invisible here. And control characters below U+0020 are left alone in every mode, because numeric references to most of them are not valid HTML — if your text contains them, the problem is upstream of escaping.
Frequently asked questions
Which characters do I have to escape in HTML?
Ampersand and less-than always, greater-than by convention, and the quote character you used around an attribute value. Escaping all five covers text nodes and quoted attributes, which is where almost all HTML injection happens.
Do I still need entities for accented characters?
No, not on a UTF-8 page, which is every page now. Type them directly. Entities are still useful for characters that are invisible or ambiguous in source, such as a non-breaking space or a soft hyphen.
Why does this write ' instead of '?
Because ' was never part of HTML 4. It works in HTML5 and XML, but older parsers and several email clients show it as literal text. The numeric form works everywhere.
Is escaping HTML enough to prevent XSS?
Only in HTML text and quoted attribute values. It does nothing inside a script block, inside a URL attribute, or in CSS — a javascript: URL survives entity escaping unharmed. Escape for the context you are actually writing into.
Why does an emoji become one entity here and two somewhere else?
Because emoji sit above U+FFFF and JavaScript stores them as two code units. Tools that loop over string indexes emit two broken references. This one iterates by code point and emits a single correct reference.
Last updated September 19, 2026