HTML Entities

Encode and decode HTML text

Loading tool…

About HTML Entity Encoder & Decoder

HTML Entity Encoder & Decoder escapes the characters that would otherwise be read as markup, and turns an entity-laden string back into the characters it represents. Encoding uses the browser's own text serializer, so the result is exactly what a browser considers safe inside an HTML text node, and decoding uses the browser's parser, so every named, decimal, and hexadecimal reference is resolved the way a page would resolve it.

Escaping is not a property of a string, it is a property of the place the string is going: an HTML text node, a quoted attribute, a script, a URL, and an SQL statement each need different treatment. This tool covers the first context precisely and the second only partly, which is worth knowing before you paste its output into an attribute. Entities matter in the opposite direction too: text pulled out of a feed, a CMS field, or a scraped page often arrives encoded once too often.

How to use this developer tool

  1. Choose Encode to turn characters into entities, or Decode to turn entities back into characters.
  2. Paste the fragment, feed field, or snippet you want to inspect.
  3. Run the conversion and compare the two panes character by character, paying attention to ampersands and quotation marks.
  4. Copy the result into the context it was prepared for, and use a real templating engine rather than this tool for values that will be inserted into attributes or scripts.
  5. When decoding, run the conversion once and check the result; a value that still contains entities was encoded more than once.

Worked example: escaping a snippet for display

An anchor tag that has to appear as literal text in an article. The space before ok is a non-breaking space pasted in from a word processor.

Input
<a href="report.php?year=2026&page=2" title='Q1 & Q2'>5 > 3 ok</a>
Encoded
&lt;a href="report.php?year=2026&amp;page=2" title=&#39;Q1 &amp; Q2&#39;&gt;5 &gt; 3&nbsp;ok&lt;/a&gt;

Three things are worth reading closely. The ampersand inside the URL became an entity, the single quotes became numeric references, and the invisible non-breaking space surfaced as a visible entity. The double quotes were left alone, because a double quote cannot terminate anything inside an HTML text node.

What this encoder changes, and where it matters

The first three rows are required in every HTML context. The rest explain the choices that surprise people.

CharacterEncoded asRequired inNote
&&amp;text and attributesMust be first, or you double-encode everything else
<&lt;text and attributesStarts a tag
>&gt;textNot strictly required, but conventional
'&#39;single-quoted attributesAdded by this tool; the browser serializer leaves it alone
"left unchangeddouble-quoted attributesEscape it yourself if the output goes into an attribute
U+00A0&nbsp;nowhere, but revealingMakes an invisible pasted character visible
é, 中, 🚀left unchangednowhereA UTF-8 page needs no entity for these

Troubleshooting

The encoded value breaks an HTML attribute.

Why it happens Text-node serialization does not escape double quotes, so a value containing one terminates a double-quoted attribute early. This tool escapes single quotes but not double quotes.

Fix Either wrap the attribute in single quotes, which the output already protects, or replace each double quote with the named reference for it before inserting. Better still, let a templating engine escape attribute values, since it knows which context it is writing into.

Users see &amp; or &lt;b&gt; on the page instead of the intended characters.

Why it happens The value was escaped twice: once by hand and once by the framework at render time. Every ampersand from the first pass is escaped again in the second.

Fix Escape exactly once, at the boundary where the value enters HTML. Decoding is a single pass, so decode here until the output stops changing: each pass you need is one layer that escaped without being asked.

Text changes meaning after a round trip, for example 1 &lt 2 becomes 1 < 2.

Why it happens HTML keeps a legacy list of named references that the parser resolves even without the closing semicolon, including lt, gt, amp, copy, and reg. An ampersand followed by one of those names is decoded whether you meant it or not.

Fix Always terminate entities with a semicolon, and escape every literal ampersand as its entity before a value reaches HTML. This is why encoding the ampersand first is not optional.

A decoded string fails a comparison that looks like it should match.

Why it happens Decoding a non-breaking space entity produces U+00A0, which looks exactly like a space but is a different code point, so equality checks, keyword matching, and trimming all behave differently.

Fix Normalize whitespace after decoding, replacing U+00A0 with a regular space when the value is meant to be plain text.

When this tool is the right choice

  • Preparing a code snippet or a tag name so it appears as literal text in an article or a documentation page.
  • Decoding a title or summary pulled out of an RSS feed, an API field, or a CMS export.
  • Finding out whether a value was escaped once or twice when something renders wrong in production.
  • Revealing invisible characters, especially non-breaking spaces pasted in from a document.

When to use something else

  • Making untrusted input safe. This covers the HTML text context only; attributes, script blocks, style blocks, and URLs each need their own escaping, and a sanitizer is what removes dangerous markup.
  • Escaping values for a URL. Percent-encoding is a different scheme entirely; use the URL Encoder & Decoder.
  • Escaping for XML. XML defines only five named entities, so &nbsp; is not valid there; use the XML Formatter and write a numeric reference instead.

Privacy and data handling

Both directions run in this browser tab using detached DOM nodes that are never inserted into the page, so nothing is executed, requested, or uploaded. Decoding a fragment containing a script tag is therefore safe here; the string is parsed as text, not as markup. That safety belongs to this page only, and says nothing about what happens when you paste the same value into an application.

Related developer tools

Frequently asked questions

Is entity encoding enough to prevent XSS?

Not on its own. It stops markup from being interpreted in the HTML text context, but the same value inside an attribute, an inline script, or a URL needs different handling. Output encoding chosen per context, plus a sanitizer for rich text, is the actual defence.

Why is the double quote not encoded?

Because the encoder serializes the value as an HTML text node, where a double quote has no special meaning. It only matters inside a double-quoted attribute, which is a context this tool does not target.

Named entities or numeric references?

Both are equivalent to the parser. Named references are more readable for the handful everyone knows; numeric references are unambiguous and available for every code point, which is why this tool writes the single quote numerically.

Do I need entities for accented or Chinese characters?

No, provided the page declares UTF-8. Entities for those characters are a legacy of pages served in single-byte encodings and only make the markup larger and harder to read.

Is decoding a string with a script tag dangerous here?

No. The decoder parses into a detached textarea, which treats its content as raw text; no element is created and nothing is inserted into this page. The decoded string can of course be dangerous somewhere else.

Why does &apos; appear in some documents but not in this output?

It is defined in XML and in HTML5, but not in HTML 4, so older tools avoid it. The numeric reference for the apostrophe works everywhere, which is why it is the safer choice.