HTML Entity Encoder / Decoder

Convert special characters into HTML entities — and decode entities back into readable text — with named and numeric forms, a live preview of exactly what the browser renders, and a searchable reference of every named entity.

Paste text and the conversion runs live as you type. On the Encode tab you pick the form — named entities (é, —), named with a numeric fallback, decimal (©) or hexadecimal (©) — and the scope (the five characters that must be escaped, every non-alphanumeric character, or literally everything). Every character is shown in a breakdown table, and the rendered preview shows what the browser will actually display. The Decode tab reverses it: named, decimal and hex entities, decoded exactly the way a browser decodes them (all 2,125 HTML5 names, including the 106 legacy forms that work without a trailing semicolon), with unknown references flagged by position and invalid code points replaced with U+FFFD — just like a browser. The Entity Reference tab is a searchable table of all 1,446 named entities — click any row to copy it.

🔒 100% private — nothing is uploaded or stored. Your text is converted entirely in your browser with plain JavaScript. It never touches our servers, is never written to disk, and the page keeps working even if your internet connection drops — which matters, because the text you encode is often exactly the kind of thing (customer data, markup with secrets, log excerpts) you would rather not paste into a third-party web service.

Text → HTML entities



Type or paste text above — conversion runs as you type.

Rendered preview

What a browser displays when it parses your encoded output — this is the point of encoding: the entities below turn back into the characters on the left.

Nothing to preview yet.

What got encoded?

Every character in your input and what it became. Blue rows changed; grey rows were outside the selected scope and passed through untouched.

Nothing to show yet.

What are HTML entities?

HTML uses < to start tags and & to start character references, so neither of those characters can appear in your text as themselves — the browser would read them as markup. An entity (formally, a character reference) is the escape form: &lt; displays as <, &amp; displays as &. There are three forms, all shown below rendering the same character:

FormExampleDisplays asNotes
Named&copy;©Readable and greppable, but only 1,446 characters have names — no named entity exists for emoji, CJK or most symbols
Decimal numeric&#169;©Works for any character: &# + the code point + ;
Hex numeric&#xA9;©Same, in hexadecimal — more compact for high code points (€ is &#8364; but &#x20AC;)

The five characters you must always escape

CharacterEntityWhy it bites
&&amp;Always. It starts a character reference — an unescaped & in “Tom & Jerry” can swallow nearby text into a bogus entity or break the page
<&lt;Always. It starts a tag — unescaped <script> in a paragraph becomes live, executable code
>&gt;Almost always. A stray > rarely breaks HTML parsing, but it is required for correctness (and mandatory in XML, including inside <![CDATA[…]]> handling)
"&quot;Inside double-quoted attributes — an unescaped quote ends the attribute early and the rest of the value becomes new attributes
’&#39; (or &apos;)Inside single-quoted attributes — same problem as above. &apos; is an HTML5 (and XML) entity; HTML4 writers used &#39;

The order of escaping matters if you roll your own: replace & first, or the ampersands you just introduced get escaped a second time.

Named vs numeric: which should I use?

Named entities are self-documenting (&mdash; tells you what it is without a hex calculator), but the named set is small: 1,446 characters. Everything else — emoji, accented letters beyond Latin, CJK, mathematical alphanumerics — only has numeric forms. If your content is plain English prose, named is pleasant. If it is arbitrary user text, a log line or a JSON payload, numeric (or named-with-numeric-fallback, this tool’s second mode) is the safe choice because it can represent every character in the input.

Browsers decode all 2,125 recognised names — the canonical ones plus legacy aliases such as &AMP; and &COPY;. This tool’s decoder implements the full HTML5 table, so what you see here is what a browser will render.

The semicolon gotcha

In HTML5 a named reference is only recognised if it ends with ; — with one legacy exception. 106 names (the old HTML 2/3 set: &amp, &lt, &copy, &nbsp, …) also decode without the semicolon, for compatibility with ancient pages. So &copy displays © in a browser, but &amper; displays literally as &amper; — the browser never trims a name to find a shorter match inside it. XML and SGML have no such exception: the semicolon is always mandatory there. The Decode tab has a switch for both behaviours.

Common pitfalls

  • Double encoding. If your output contains &amp;lt; (which displays as the text &lt;), something escaped an already-escaped string. Decode once, not twice — the same bug as %2520 in URL encoding.
  • Escaping twice in application code. A template engine that auto-escapes plus a manual escape() call produces the same &amp; symptom. Pick one layer and escape exactly there.
  • & in URLs inside HTML. In href="https://x.com/?a=1&b=2" the & separating query parameters must be written &amp; in the markup. Browsers tolerate the bare form; validators (and some XML pipelines) do not.
  • &nbsp; is not a space. It is U+00A0, the non-breaking space. An ordinary space (U+0020) has no named entity — in named mode this tool leaves it alone, and in numeric mode it becomes &#32;.
  • Decoding is not sanitising. Decoding user-supplied entities and inserting the result into a page as HTML re-introduces whatever the entities were hiding (&lt;script&gt; decodes to a live tag). Decode for display as text; re-encode before inserting into markup.
  • Entities in attributes. A & in an attribute value must be &amp; regardless of whether the attribute uses single or double quotes — the quote-style rules above only cover the quote characters themselves.

From the command line

The same two operations exist in every language. Python’s standard library does both: html.escape(text, quote=True) and html.unescape(text). PowerShell has [System.Net.WebUtility]::HtmlEncode() / HtmlDecode(). JavaScript has no built-in — which is why this page exists.

Nothing on this page leaves your browser: there is no server round-trip when you type or paste, no analytics on your inputs, and no storage of any kind.


Luke Keam
Thank you for reading. Email me: [email protected]
Luke Keam | techgeek.biz