Why HTML needs entities at all
HTML uses < and > to delimit tags and & to start entity references — which creates a problem the moment you want to display those literal characters as text rather than have the browser interpret them as markup. Typing a raw < into page content risks the browser trying to parse whatever comes after it as a tag. HTML entities solve this: they're an escape mechanism, a way to say "render this character literally" instead of "interpret this as markup."
Three ways to write the same entity
Named: < & ©
Decimal: < & ©
Hex: < & ©
All three forms render identically (<, &, ©). Named entities are more readable but only exist for a fixed, defined set of characters (HTML5 defines over 2,000). Numeric entities (decimal or hex) can represent any Unicode code point, including characters with no named entity at all — which is why numeric entities are the fallback for anything outside the common named set.
| Character | Named | Decimal | Hex |
|---|---|---|---|
< |
< |
< |
< |
> |
> |
> |
> |
& |
& |
& |
& |
" |
" |
" |
" |
' |
' (no widely supported named form) |
' |
' |
© |
© |
© |
© |
| Non-breaking space | |
  |
  |
The five characters that actually matter for safety
Only five characters are dangerous enough in HTML to require escaping in nearly every context: <, >, &, ", and '. Everything else (emoji, accented letters, ©, etc.) can usually be written as a literal UTF-8 character directly in a modern, UTF-8-declared document — entities for those are a convenience for constrained encodings, not a requirement.
Why this is a security issue, not just a display issue
If user-supplied content is inserted into an HTML page without escaping these five characters, an attacker can inject <script> tags or event handler attributes that execute in another user's browser — this is the core mechanism behind stored and reflected XSS (cross-site scripting). <script> displays as harmless text; an unescaped <script> executes. Every templating engine and framework (React's JSX, Vue templates, Django templates, etc.) escapes interpolated values by default for exactly this reason — the moment you bypass that default (dangerouslySetInnerHTML in React, |safe in Jinja2, v-html in Vue), you've taken on the responsibility of escaping correctly yourself.
Context matters: HTML escaping isn't universal
Escaping rules differ by context, and using the wrong one is itself a vulnerability:
- HTML body text — escape
<,>,&. - HTML attribute values — also escape quotes (
"or', matching whichever the attribute uses). - URLs — need percent-encoding (see Complete Guide to URL Encoding), not HTML entities.
- JavaScript string literals embedded in HTML — need JavaScript string escaping first, then HTML escaping for the surrounding markup — mixing these up is a common source of both broken pages and injection bugs.
Common mistakes
- Double-encoding. Escaping already-escaped text turns
&into&amp;, visibly breaking the display. - Escaping only
<and>but forgetting&. A literal ampersand in text (e.g., "Q&A") can break subsequent parsing if not escaped, since&starts every entity reference. - Assuming entity-encoding is sufficient inside a
<script>block. HTML entities aren't decoded inside<script>content — you need JavaScript-appropriate escaping there instead. - Relying on entities as your only XSS defense. Escaping output is necessary but not sufficient on its own — a real defense also validates/sanitizes input and uses a Content-Security-Policy.
FAQ
Do I need to encode every non-ASCII character as an entity?
Not in a modern, UTF-8-declared document — only the five HTML-significant characters (< > & " ') need mandatory escaping; other Unicode characters can be written literally.
What's the difference between < and <?
Nothing rendered — one is decimal 60, the other is hex 3C, both referring to the same Unicode code point for <. Pick whichever is more convenient to generate.
Is HTML entity encoding the same as URL encoding?
No — they solve different problems and use different escape rules; URL encoding uses %XX percent-escapes for characters unsafe in URLs, while HTML entities use &name; or &#NNN; for characters unsafe in HTML markup.
Does escaping alone prevent XSS?
It's the primary defense for output, but a complete strategy also validates input, avoids unsafe sinks like innerHTML with untrusted data, and layers in a Content-Security-Policy header.
Convert between raw characters and HTML entities instantly with the HTML Entities tool — everything runs client-side.