Convert special characters in your text into HTML entities so your content displays correctly and doesn’t break HTML markup.
<, >, &, ", '. Toggle "encode non-ASCII" to also entity-encode characters above U+007F (accents, CJK, emoji) for legacy systems that don't speak UTF-8.&, ©) are readable; numeric references (&, &) work in every parser including XML and ancient mail clients. Numeric is the safer default for cross-system pipelines.Five ASCII characters — <, >, &, ", ' — carry structural meaning in HTML. If you drop them into a page unescaped, the browser treats them as markup, and at best your page renders wrong; at worst, a hostile string injects a <script> tag and you have a cross-site scripting (XSS) bug. Entity encoding swaps each reserved character for a &name; or &#nnnn; reference that the parser displays as text instead of interpreting as syntax. The OWASP XSS Prevention Cheat Sheet lists these five characters as the minimum mandatory set for HTML body context.
<script>alert(1)</script> to <script>alert(1)</script> neutralizes the injection — the browser shows the literal text instead of executing it.<div class="hero"> only displays if you encode it as <div class="hero">.". Encode quotes to " (or ") so values like title="She said \"hi\"" survive intact. URLs in href also need & encoded as & to prevent the parser from looking for an entity reference inside the query string.© instead of ©) render reliably across Gmail, Outlook, Apple Mail, and Yahoo where named entities sometimes don't.wp_kses filter, and PHP htmlspecialchars() all assume entity-encoded input. Pre-encoding before storage avoids surprises on read.| Character | Named Entity | Decimal | Hex | Notes |
|---|---|---|---|---|
& (ampersand) |
& |
& |
& |
Escape FIRST when encoding manually — otherwise you double-encode existing entities |
< (less-than) |
< |
< |
< |
Opens an HTML tag if left raw |
> (greater-than) |
> |
> |
> |
Closes a tag; less critical than < but escape for symmetry |
" (double quote) |
" |
" |
" |
Required inside double-quoted attribute values |
' (apostrophe) |
' (XHTML/HTML5 only) or ' |
' |
' |
' is NOT defined in HTML 4 — use ' for max compatibility |
| Format | Example | Coverage | Best For |
|---|---|---|---|
| Named reference | &, ©, — |
~2,231 entities in HTML5 spec | Human-edited HTML, readability |
| Decimal numeric | &, ©, — |
Any Unicode code point U+0001 to U+10FFFF | XML, RSS, legacy email, JSON-in-HTML |
| Hex numeric | &, ©, — |
Same range as decimal, terser for high code points | Code generators, dense Unicode (emoji at U+1F600+) |
All three forms produce identical rendered output. Named references existed in HTML 4 but the count exploded in HTML5 — ' is one example that XHTML 1.0 and HTML5 accept but HTML 4 does not. When in doubt, decimal numeric references work everywhere.
Five: <, >, &, ", and '. These are the OWASP-recommended minimum for the HTML body context. In attribute context, OWASP recommends a stricter rule — encode every non-alphanumeric character below U+00FF using &#xHH; format — because attribute parsers accept a wider range of breakouts. For everyday HTML body content, the five-character set is sufficient.
' safe to use?It depends on the doctype. ' is defined in XML, XHTML 1.0, and HTML5, but it was NOT defined in HTML 4. A page served as <!DOCTYPE html> (HTML5) renders ' correctly in every current browser. A page served as HTML 4.01 Strict/Transitional may render the literal text ' in older user agents. For maximum portability — especially when targeting old email clients, RSS readers, or legacy CMS pipelines — use ' (decimal) or ' (hex) instead.
Named references win on readability — — is obvious; — is not. Numeric references win on portability — they work in XML, JSON-in-HTML, and email clients that lack the HTML5 entity table. A reasonable rule: hand-written HTML uses named references for the common ~30 entities (&, <, >, ", , ©, —, …, etc.); generated/machine output uses decimal numeric references for everything.
No — they're three different schemes for three different contexts.
&name; or &#nnnn; — for embedding text inside HTML content or attributes.%XX — for query strings, paths, and form bodies. Use the URL encoder for that.&/</>/"/' set as HTML5 but the named-entity table is much smaller (just those five). For arbitrary Unicode in XML, use numeric character references.Picking the wrong scheme is a classic injection bug — entity-encoding a URL leaves % and ? exposed; URL-encoding HTML produces %3C instead of <, which the browser shows as literal text instead of a tag.
For HTML body context — yes, encoding the five characters before insertion stops the canonical <script> injection. But XSS prevention is context-sensitive. If you're inserting user data into a JavaScript string, a CSS url(), an attribute name (vs value), or an unquoted attribute, HTML entity encoding alone is NOT enough — you need JS escaping (\xHH), CSS escaping (\HH), or, ideally, you should redesign so user data never lands in those positions. See OWASP's cheat sheet for the full context matrix.
&amp; show up?Double encoding happens when text that's already entity-encoded gets encoded a second time. The first pass turns & into &. The second pass sees the literal & at the start of & and turns it into &amp;. The browser then displays the literal text & instead of the intended &. Fix: encode raw text exactly once, immediately before insertion into HTML. If you must round-trip, decode fully before re-encoding, or use a templating engine (Jinja, Handlebars, React JSX) that auto-encodes on output and tracks encoding state.
element.textContent = userInput look safe but innerHTML is dangerous?In the DOM, textContent and innerText treat their input as plain text — the browser automatically escapes <, >, and & before insertion, so userInput = "<script>alert(1)</script>" shows up as visible text and never executes. innerHTML parses its input as HTML, so the same string injects a (dormant — modern browsers don't run script tags inserted via innerHTML, but <img onerror> and other event handlers still fire). Rule of thumb: prefer textContent for any string that started outside your code. If you absolutely need innerHTML, entity-encode the user portion first.
Emoji like 😀 (U+1F600) and other Supplementary Plane characters are encoded as a single numeric reference using the full code point — 😀 decimal or 😀 hex. The HTML spec accepts code points up to U+10FFFF in numeric references. The encoder does NOT emit UTF-16 surrogate pairs (��) because the HTML parser interprets those as two separate (invalid) code points. JavaScript's internal string representation uses surrogate pairs, but that's a JS implementation detail — for HTML output, emit the single code point.
Yes — entity encoding is fully reversible. Paste the output into the HTML Entity Decoder to recover the source. This round-trip is useful for verifying you haven't double-encoded, for extracting plain text from scraped HTML, or for debugging entity issues in a CMS pipeline.
Related developer tools: HTML Entity Decoder · URL Encoder · URL Decoder · Base64 Encoder/Decoder · JSON Formatter · JWT Decoder