HTML Entity Encoder & Decoder

Encode text so markup shows as text, or decode entities back again. Choose how much to encode: markup only, quotes too, or everything above ASCII.

Enable JavaScript to customise; default output below.

Nothing is uploaded. The conversion happens in this tab.

Direction
Encode

Quotes matter inside an attribute value. Above ASCII matters when the page encoding is not UTF-8.

More options Show
Live preview encoded.txt
<a href="/plugins?sort=new&page=2">Tom & Jerry's "café" — 50% off</a>

Output is valid and updates as you type.

Encode text so a browser shows it instead of running it, or decode entities back into the characters they stand for.

How to use

  1. Paste the text. Encoding turns the characters that mean something to a parser into references; decoding does the reverse.
  2. Choose how much to encode. Markup only covers the three characters that change structure; add quotes when the text goes inside an attribute value.
  3. Use “everything above ASCII” when the page is not served as UTF-8, or when a system down the line mangles accents.
  4. Copy the result. Encoding is safe to repeat: running it over its own output does not double-encode.

Example

<a href="/plugins?sort=new&page=2">Tom & Jerry's "café" — 50% off</a>

With markup and quotes:

&lt;a href=&quot;/plugins?sort=new&amp;page=2&quot;&gt;Tom &amp; Jerry&apos;s &quot;café&quot; — 50% off&lt;/a&gt;

The accented é, the em dash and the percent sign are untouched, because none of them change how a parser reads the text.

Pitfalls

  • Encoding is not sanitising. &lt;script&gt; is safe to display, but escaping on the way in to the database and then again on the way out gives you visible &amp;lt; in the page.
  • The order matters. Ampersands have to be encoded first, or < becomes &amp;lt; instead of &lt;. That order is what makes a second pass here harmless.
  • &apos; is HTML5 and XML, but not HTML4. Use &#39; if something very old has to read it.
  • An attribute value needs its quote character encoded, and nothing else. Encoding the whole attribute is why class="&amp;quot;x&amp;quot;" shows up in page source.
  • A bare ampersand in text is technically an error but every browser recovers from it. Decoding here leaves it alone rather than guessing where the entity was meant to end.
  • Named references number in the thousands. This decodes the ones that appear in real content; anything else is left visible so you can see what it was.
  • Numeric references above the Unicode range, and the surrogate halves, are not characters. They stay as references rather than becoming replacement characters.
  • Percent encoding is a different thing. %20 is for URLs, and belongs to the URL encoder.

Compatibility

The five markup references are defined by both HTML and XML, so they work everywhere. Numeric references, decimal or hexadecimal, are equally universal. The named references decoded here are the HTML5 set that appears in real content. Everything runs in your browser, with no upload and no DOM parsing, so the behaviour is the same in every browser from 2017 onwards.

Frequently asked questions

Which mode do I want for a database value?
Neither. Store the raw text and escape it when you output it, in the context you output it into.
Why is the é not encoded?
Because it does not need to be in a UTF-8 page. Switch to “everything above ASCII” if your output is not UTF-8.
Does this protect against XSS?
It protects against text being read as markup, which is one part. The full answer depends on where the value ends up: an attribute, a URL and a script each need different escaping.
What about &nbsp;?
It decodes to a non-breaking space, which looks like an ordinary space but is a different character. That is often the invisible difference in a line that will not wrap.
Can I encode only some characters?
Yes, that is what the scope does. Markup only leaves quotes and everything else as it was.
Weekly drops

New tools, when there are new tools

One email when something worth using ships. No schedule to fill, so no filler.

Your address goes nowhere else, and one click unsubscribes.