Solved.tools — Free Online Calculators & Tools

We use cookies for analytics and advertising. Learn more about our cookie policy

HTML Entity Encoder & Decoder

Last updated: 14 August 2026

Reviewed by Gavin · Research and drafting assisted by AI

27 chars · 27 bytes
49 chars · 49 bytes · size ratio 1.81×
The five characters that always need escaping& < > " '
Numeric format&#169; (decimal)
Astral / emoji😀 → &#128512;
Round-trip identitycheck after decoding
Was this helpful?


HTML Entity Encoder & Decoder

An HTML entity is a short sequence of characters that represents a single Unicode character inside an HTML document. The sequence always starts with an ampersand (&) and ends with a semicolon (;), and in between sits either a name (&amp;, &copy;, &eacute;) or a numeric body (&#169; for decimal, &#xA9; for hexadecimal). The browser's parser replaces each recognised entity with the single character it refers to before the document is shown, so &copy; displays as the copyright sign © and &#xA9; displays as the exact same character. The full list of named entities, together with the rules for matching them, is defined by the WHATWG HTML Living Standard in section 13.5, Named character references, which in turn defers to the Unicode Standard and ISO/IEC 10646 for the underlying code points.

HTML entities exist for two historical reasons. The first is that the early web was a Latin-1-only world and there was no way to put a non-Latin character, an accented letter, a typographic punctuation mark, or a mathematical symbol into a document without a numeric reference. Names such as &eacute; and &copy; were a human-readable shortcut over the equivalent numeric form, and they are still useful today because a name like &nbsp; is far easier to remember than &#160;. The second reason, which is the only one that still matters in practice, is escaping: a handful of characters have a special meaning in HTML markup itself (&, <, >, ", '), and writing them as entities lets you put a literal ampersand or angle bracket inside the document body without confusing the parser.

How to Use the Encoder & Decoder

  1. Choose a direction. Encode turns plain text into entities; Decode turns entity-encoded HTML back into plain text.
  2. For encoding, pick an encode mode: Minimal (only the five special characters), All non-ASCII (every code point above 127 as a numeric entity), or Named where possible (named entities from the WHATWG table, numeric fallback for the rest).
  3. Pick a numeric format: Decimal (&#169;) or Hexadecimal (&#xA9;). Hex matches the WHATWG recommended form.
  4. Type or paste into the input box. The output updates as you type, no submit button.
  5. Use the per-field Copy buttons to grab either side.
  6. The reference card at the bottom shows the round-trip status. After encoding, paste the output back into the input with the direction set to Decode and confirm the result matches your original.

The Five Characters That Always Need Escaping

Only five characters have a special meaning inside HTML text or an attribute value, and they are the only ones that must be escaped for the document to remain well-formed:

  • & becomes &amp; (otherwise it starts an entity reference).
  • < becomes &lt; (otherwise it starts a tag).
  • > becomes &gt; (not strictly required inside text content, but conventional and harmless, > is required inside ]]> to avoid being parsed as the end of a CDATA section).
  • " becomes &quot; (required inside an attribute value wrapped in double quotes; optional elsewhere).
  • ' becomes &apos; (required inside an attribute value wrapped in single quotes; optional elsewhere, and the entity is HTML5 only; HTML4 does not define it).

Every other character, including every accented Latin letter, every CJK ideograph, every emoji, and every mathematical symbol, can be written directly in an HTML document served as UTF-8. The HTML 4 specification required a numeric reference for many of these characters because the document might be served as Latin-1, but that constraint has not applied to real-world documents for many years.

Encode Modes

Minimal / HTML-safe. Only the five characters above are escaped. This is the right default for inserting user-supplied text into a document body or attribute value, and it is the mode that produces the smallest, most readable output. For an ASCII string with no special characters, the output is byte-for-byte identical to the input.

All non-ASCII. Every character above code point 127 (i.e. outside the basic 7-bit ASCII range) is also escaped as a numeric entity. This mode is appropriate when the document will be served through a channel that cannot be relied upon to honour the declared charset, or when you want the entity-encoded form to be safe to drop into a context that might interpret byte values differently (an older email gateway, a Latin-1-only textarea, a hex dump in a bug report). Decimal or hex numeric entities are equally valid; the hex form matches the WHATWG recommendation and is typically more compact for code points above 256.

Named where possible. The encoder uses the named entity from the WHATWG table wherever one exists, &copy; for ©, &eacute; for é, &trade; for ™, &nbsp; for the non-breaking space, and falls back to a numeric entity for everything else. This mode produces the most human-readable output and is the best choice when the result will be edited by hand later. It does mean that a string containing a Chinese character or an emoji will still have numeric entities for those characters, because no named entity exists for them.

Numeric Entities: Decimal and Hexadecimal

Numeric entities come in two flavours. The decimal form is &#169; (the code point as a base-10 integer). The hexadecimal form is &#xA9; (the code point as a base-16 integer, with x or X as the prefix per the HTML standard, and either upper- or lowercase hex digits). Both forms decode to the same character; the hex form is shorter for code points above 256 (four hex digits are typically shorter than five decimal digits) and matches the form you will find in the WHATWG named-character-references table.

The encoder always emits the hex form in uppercase, matching the canonical WHATWG style. The decoder accepts both cases for both the prefix and the digits: &#XA9;, &#xa9;, &#Xa9;, &#xA9; all decode to ©.

Named Entities and the Non-Breaking Space

The named-entity table contains roughly 2,200 entries per the WHATWG standard, spanning the Latin-1 supplement, Greek and Cyrillic letters, a large set of typographic punctuation marks and arrows, common mathematical operators, and a number of legacy aliases. The most important named entity is &amp;, which is the only one whose presence is required for safe escaping, every other named entity is purely a convenience for human readability. The second most important is &nbsp;, the non-breaking space (U+00A0). Unlike a regular space, a non-breaking space prevents the browser from breaking a line at that point, which makes it useful for keeping units attached to their numbers ("200 kWh"), honouring typographic conventions in French and other languages, and preventing awkward wraps inside code samples and URLs. Be aware that pasting text from a word processor often introduces non-breaking spaces invisibly, which is one reason the round-trip identity check matters: if the input contained a U+00A0 and the encoder-decoder pair turns it into a regular space, the round-trip is no longer exact.

The related invisible characters &#8203; (zero-width space), &#8204; (zero-width non-joiner), &#8205; (zero-width joiner), and the byte-order-mark &#65279; are also worth knowing about. They are valid Unicode characters, they render as nothing on screen, and they frequently appear in text copied from web pages, databases, and rich-text editors. They can quietly break string comparisons, regex matches, and unique-key indexes. A round-trip test through the encoder-decoder pair is one of the easier ways to spot that they are present.

Decode Behaviour and Double-Encoding

A correct decoder is single-pass. Given the input &amp;lt;, the first sweep replaces the named entity &amp; with the literal ampersand character, leaving &lt; in the output. It must NOT then re-process the output to replace &lt; with <, because the original input contained a literal &lt; that the user wanted preserved. Double-decoding is a real-world bug in templating systems that escape user input twice "for safety"; the result is that an attacker who submits &lt;script&gt; ends up with <script> rendered into the page after the second decode pass. The single-pass decoder in this tool follows the WHATWG rule: only well-formed entities are replaced, and unknown entities are passed through verbatim. That means &notarealentity; decodes to itself, &amp;lt; decodes to &lt;, and only &lt; decodes to <.

The encoder side has the same property in reverse: encoding <script>alert("x")</script> in minimal mode produces &lt;script&gt;alert(&quot;x&quot;)&lt;/script&gt;, and running that output through the decoder returns the original string byte-for-byte. That round-trip identity holds for every mode and every format, including supplementary-plane characters such as 😀 (U+1F600), which encodes to a single &#x1F600; in hex mode and decodes back to the original code point.

Astral-Plane Characters and Emoji

The Unicode code-space extends well past the original 16-bit Basic Multilingual Plane. Code points above U+FFFF, emoji, most CJK extensions beyond the original 1993 set, mathematical alphanumeric symbols, supplementary-plane ideographs, are encoded in JavaScript strings as a pair of UTF-16 surrogate halves. A naive encoder that uses String.prototype.charCodeAt walks the string 16 bits at a time and sees two surrogate code units (0xD83D and 0xDE00 for 😀) instead of the single supplementary code point (0x1F600). Treating each surrogate as a separate character produces two malformed entities that do not decode back to the emoji. The encoder in this tool iterates with a for…of loop and reads each code point with String.prototype.codePointAt, so an emoji produces exactly one numeric entity (&#x1F600;) and decodes back to exactly the original character. The decoder mirrors this with String.fromCodePoint, which understands surrogate pairs and supplementary code points.

Entity Escaping Is Not Sufficient Inside <script>, URLs, or CSS

Escaping the five characters is the correct rule for HTML text content and for HTML attribute values wrapped in matching quotes. It is NOT sufficient in three other contexts where HTML entities are not interpreted by the consumer:

  • Inside a <script> block. The HTML parser passes script content to the JavaScript engine verbatim. A < in a script literal is a less-than operator or a tag-start depending on where it sits, and a string like "\u003cscript\u003e" decodes to "<script>" before the script runs. To inject user input safely into JavaScript, escape the JavaScript-string syntax: backslash-escape quotes and backslashes, and write < as \u003c. The OWASP XSS Prevention Cheat Sheet calls this rule "Rule #1" and warns explicitly against relying on HTML entity encoding inside a script block.
  • Inside a URL. Browsers do not decode HTML entities in URL components. The URL https://example.com/?q=&lt;script&gt; requests a literal &lt;script&gt;, not <script>. To embed user input in a URL, percent-encode the unsafe characters (%3C for <, %3E for >, %26 for &, %3F for ?) using encodeURIComponent in JavaScript.
  • Inside a CSS string. CSS content strings and url() values are also passed through unchanged. content: "\003c"; is the CSS form of an entity escape and lives in a completely different syntax than HTML.

In short: HTML entity encoding is one tool in a small toolbox. The other tools are JavaScript-string escaping, percent-encoding for URLs, and CSS-string escaping. Mixing them up, typically by entity-escaping input that is then placed inside a script block, is one of the most common causes of stored XSS.

UTF-8 Has Made Most Entities Optional

In a UTF-8-encoded HTML5 document, the only entity references you actually need are the five special characters above. Every other character can be written as the literal byte sequence the user expects, including every accented letter, every CJK ideograph, and every emoji. Many older guides still recommend escaping every non-ASCII character as &#nnn; for "safety", but that advice dates from the Latin-1 era and adds noise without benefit when the document is correctly served with <meta charset="utf-8"> or a Content-Type: text/html; charset=utf-8 header. The named-entity convenience (&copy; instead of ©) is still useful because it survives copy-paste through tools that mangle non-ASCII bytes, but it is no longer required.

That said, there are still contexts where numeric entities help: legacy email gateways that strip high bytes, debug output that is shown in a non-UTF-8 terminal, source code that is compiled by a toolchain that misreads the declared charset, and HTML payloads that must survive a JSON round-trip through a system that does not preserve UTF-8. The All non-ASCII mode in this tool produces exactly the form these contexts want.

Common Mistakes

Double-encoding. A pipeline that encodes input twice, once when it is stored and once when it is rendered, produces &amp;amp; for the input &amp; and &amp;lt; for the input &lt;. The single-pass decoder in this tool turns &amp;lt; back into &lt; (the literal string the user wanted), not into <. If you suspect a double-encoding bug, run the suspect string through the decoder and check whether the output still contains entities; if it does, decode again.

Entity escaping inside <script> or href. See the section above. Escaping user input with HTML entities is the wrong defence for a script context, a URL context, or a CSS context.

Naive charCodeAt-based encoding that splits emoji. A common homegrown encoder that loops with charCodeAt will split 😀 into two surrogates and produce two broken entities. The round-trip test on the emoji preset is the easiest way to detect this, the encoded form must contain exactly one &#x…; (or &#…;) and the decoded form must contain exactly one 😀.

Assuming &apos; works everywhere. The named entity &apos; is HTML5 only. HTML 4 and XHTML 1.0 do not define it, and a strict HTML 4 validator will reject the document. Use the numeric entity &#39; if you need maximum portability, or just write ' outside a single-quoted attribute value (where it does not need to be escaped anyway).

Invisible characters breaking equality. A string with a non-breaking space, a zero-width space, or a BOM will not compare equal to the same string without them. The byte counts in the input and output rows of this tool reflect the underlying bytes; the character counts reflect Unicode code points.

Frequently Asked Questions

What is the difference between &amp;copy;, &#169;, and &#xA9;?

They all display as the same character (the copyright sign, ©). &amp;copy; is the named entity, defined by the WHATWG HTML Living Standard. &#169; is the decimal numeric entity, 169 is the Unicode code point of © in base 10. &#xA9; is the hexadecimal numeric entity, A9 is the same code point in base 16. The named form is the most readable; the hex form is typically the shortest for code points above 256; the decimal form is the form most editors default to.

How do I escape user input for safe insertion into an HTML document?

Use the Minimal mode in this tool. It escapes only the five characters that have special meaning in HTML markup (&, <, >, ", '), which is the correct rule for inserting untrusted text into an HTML body or attribute value. For inserting the same input into a <script> block, a URL, or a CSS string, use a context-specific escaper instead, entity encoding is not sufficient in those contexts.

Why does the encoder produce &#x1F600; for 😀 and not two separate entities?

Because 😀 is a single Unicode code point (U+1F600) even though JavaScript stores it internally as two UTF-16 surrogate halves. The encoder iterates by code point, not by 16-bit code unit, so it sees one character and produces one entity. A naive implementation that loops with charCodeAt will see two surrogate halves and produce two malformed entities that decode to something other than the original emoji.

Does &apos; work in HTML 4?

No, &apos; was added to the named-entity table in HTML5. HTML 4 and XHTML 1.0 do not define it. Use &#39; (decimal) or &#x27; (hex) if you need an entity that is valid in those older standards, or write ' directly outside a single-quoted attribute value.

What should I do if my document ends up with &amp;lt; instead of <?

That is double-encoding. The input < was first encoded to &lt; and then encoded again to &amp;lt;. The single-pass decoder in this tool turns &amp;lt; back into &lt;, the literal string the user originally stored, so the round-trip preserves the data. The bug is upstream: the rendering pipeline is escaping a string that was already escaped. Run the decoder once on the stored data, then fix the rendering code so it only encodes the raw input, not the already-encoded input.

Is entity encoding a complete defence against XSS?

No. Entity encoding defends against HTML-context XSS, and only when applied at the correct point in the pipeline. It does not defend against script-context XSS, URL-context XSS, CSS-context XSS, or mutation-XSS where the browser reparses a fragment differently from the way the template engine escaped it. The OWASP XSS Prevention Cheat Sheet recommends context-specific escaping: HTML body and attribute escaping, JavaScript-string escaping, CSS escaping, and URL percent-encoding, applied at the boundary between untrusted input and the context where it is being inserted.

can the HTML Entity Encoder & Decoder be used for professional or commercial purposes?

Yes, the encoder and decoder implement the WHATWG HTML Living Standard §13.5 named-entity table and Unicode Standard Annex #44 code-point rules, so the output is mathematically and semantically correct and is suitable for professional, commercial, and educational use. For high-stakes applications (security-sensitive XSS pipelines, regulatory archiving of HTML payloads, accessibility tooling), verify the output against a second implementation such as a browser's HTML parser or a security-vetted library. The references at the bottom of this page list the specific standards used.

For the HTML Entity Encoder & Decoder, How often are the underlying formulas updated?

The encode and decode rules are based on the WHATWG HTML Living Standard and the Unicode Standard, both of which are maintained as living documents. The named-entity table is stable for the vast majority of characters; new entries are rare. The decoder always accepts both decimal and hexadecimal numeric entities, and the encoder always emits well-formed output, so future changes to the named table can only add, never remove, recognised names. When standards change, this tool is updated to reflect the current authoritative source. Each version's references section lists the specific sources used.

References

  • WHATWG HTML Living Standard, §13.5 Named character references. The canonical, always-current list of named HTML entities and the rules the parser applies when matching them. Available at html.spec.whatwg.org/multipage/named-characters.html.
  • Unicode Standard Annex #44, Unicode Character Database. The technical reference for Unicode code points, names, properties, and aliases. Available at unicode.org/reports/tr44/.
  • ISO/IEC 10646, Information technology, Universal Coded Character Set (UCS). The international standard that defines the same code-point table as the Unicode Standard, maintained in lock-step.
  • OWASP XSS Prevention Cheat Sheet. Authoritative summary of the context-specific escaping rules (HTML, attribute, JavaScript, URL, CSS) needed to defend against cross-site scripting. Available at cheatsheetseries.owasp.org/cheatsheets/Cross_Site_Scripting_Prevention_Cheat_Sheet.html.

Worked example

Encode the text "café & 5 < 6" with all special characters enabled. The ampersand becomes &, the acute accent in é becomes é (or é in numeric form), the less-than sign becomes <, and the quotes, if present, become ". The encoded output is "café & 5 < 6". Paste that into an HTML file and the browser renders the original sentence exactly.