HTML Entities
html entities html entities escape syntactically significant characters and represent symbols html entities — <, &, numeric ⚠ —
Introduction
HTML entities — <, &, numeric ⚠ — represent characters that would otherwise break parsing or display.special symbols. Stripe docs encode angle brackets in API examples; Amazon product titles with ampersands must use & in HTML attributes. Staff engineers encode on output contextually — attribute, text, or URL — never assume WYSIWYG handled it.
Business problem
Unencoded ampersands and less-than signs in CMS content break HTML parsing — half the page vanishes after a product name "Fish & Chips". Double-encoding & displays literal "&" to users. International currency symbols wrong without UTF-8 plus correct entities.
- Display bugs: Shopify merchant titles with raw & break attribute values in meta tags.
- Security: Unencoded user text enables tag injection — XSS entry point.
- SEO: Broken title truncation at first unescaped & — SERP shows garbled text.
Why this feature exists
HTML syntax uses < and > as tag delimiters — literal less-than in text needs escaping. Named entities (©, ) predate Unicode ubiquity; numeric references work for any Unicode code point.
- History: HTML4 entity sets; XHTML DTD entity declarations; HTML5 named character references.
- Today: UTF-8 documents reduce entity need for symbols — still mandatory for <, >, &, quotes in attributes.
- Rejected: Encoding entire ASCII as entities — bloat and readability loss.
Browser internals
Tokenizer recognizes & starting character reference; resolves named or numeric (#decimal or #xhex) to Unicode code point. Invalid reference may consume characters differently per spec — avoid malformed references. Attribute values parse entities in quoted strings.
- Named: © → © — huge named reference table in HTML5.
- Numeric: © or © — no DTD required.
- Ambiguous: © without semicolon — legacy lenient parsing, don't rely.
Text node: Fish & Chips → Fish & ChipsAttribute: title="Tom & Jerry" → Tom & JerryInvalid: &copy → may parse differently — always use ; terminator
Rendering workflow
Entity resolution happens at parse time into DOM text nodes as actual Unicode characters — not entities stored in DOM. innerHTML re-serialization may re-escape. Font must cover code point — entity doesn't guarantee glyph exists.
- Font fallback: Rare numeric entity — missing glyph shows tofu unless font stack covers.
- Combining chars: Entity for base + combining mark — normalization affects search.
- Performance: Entity parsing negligible vs DOM size — double-encoding bloats HTML bytes.
Feature deep dive
Encode rules: In HTML text: &, <, > minimum; quotes if needed. In attributes: also encode " or ' per delimiter. Prefer UTF-8 file encoding over entity for most non-ASCII. Use entities for invisible chars (nbsp sparingly) or when editing ASCII-only sources.
- & mandatory first when encoding — & before other entities.
- nbsp: — non-breaking space — don't use for layout columns.
- hellip: … or Unicode … — typography in prose.
<p>Tom & Jerry © 2025 — price < £50</p><a href="/search?q=fish%20%26%20chips" title="Fish & Chips">Search</a><!-- API docs: encode angle brackets --><pre><PaymentIntent id="pi_123" /></pre>
Accessibility analysis
Screen readers announce resolved character — © read as "copyright" in some AT. Excessive nbsp prevents natural line breaks — dyslexia-friendly reflow harmed. Entity for decorative symbol needs aria-hidden if redundant with text.
- Language: Entity doesn't set lang — French « » still need context.
- Emoji entities: Numeric 😀 same as literal emoji for AT — description matters.
- Confusion: User sees & — double encoding hurts comprehension.
SEO impact
SERP displays decoded characters from title/meta — entities in source become symbols in snippet. Wrong encoding breaks title at parse error point. Schema.org JSON in script must be valid JSON — escape quotes, not HTML entities inside JSON strings.
- URLs: & in URL is query separator — encode as %26 in href, not & alone in URL path wrong context.
- Crawl: Broken HTML from bad entities — truncated crawl of page body.
- International: UTF-8 preferred — entities for currency symbols OK.
Security considerations
Contextual encoding is XSS defense — HTML entity encode for body text, JavaScript encode for script contexts, URL encode for href. Bypass via malformed entities historically — modern parsers strict enough but don't test exploits manually.
- Attribute breakout: " onmouseover= without encoded quote in attribute value.
- Double decode: Server decode then HTML insert — second-order XSS.
- Template engines: Auto-escape must know HTML vs URL context — Stripe Liquid escape filters.
Performance impact
Entity bloat — encoding every non-ASCII as ...; — increases HTML size vs UTF-8 bytes. Amazon templates use UTF-8 throughout; entities only where syntactically required.
- Compression: Brotli compresses repeated entities well but UTF-8 still smaller for CJK.
- Parse: Long numeric entity chains in generated HTML — minor tokenizer cost.
- CDN: charset=utf-8 header must match — entities don't fix wrong bytes.
Real production example
Shopify Liquid — {{ product.title | escape }} for HTML context; | url_encode for query params. BBC CMS encodes on publish; editors type literal & in UI — stored UTF-8, encoded on HTML render.
- Layers: DB UTF-8 → template escape on output → never trust stored HTML from users without sanitize.
- Tests: Fixture product names with & < > " ' in snapshot tests.
- JSON-LD: Separate JSON serializer — not HTML entity encoder.
<title>{{ page_title | escape }} | {{ shop.name | escape }}</title><meta property="og:title" content="{{ page_title | escape }}">
Enterprise usage
Enterprise templating mandates auto-escape by default; raw HTML blocks require security review. OWASP Encoder libraries per context documented in security guide. Pre-commit tests with malicious entity strings.
- CMS: WYSIWYG stores canonical Unicode; renderer encodes.
- i18n: RTL marks as Unicode not entity unless needed.
- Email: Entities more common in ASCII email — separate pipeline rules.
Common production failures
Product feed import with raw & in 40k titles broke Google Shopping HTML landing pages — meta tags truncated; emergency batch escape job.
- Double encode: &amp; visible on site after nested template escapes.
- XSS: Review comment with <script> entity-decoded server-side wrongly — patched encoder context bug.
- Legal: © without actual copyright ownership — content issue surfaced in entity audit.
Architecture review questions
- Are &, <, > encoded in HTML text and attributes where required?
- Is UTF-8 declared and used instead of numeric entities for most i18n text?
- Do template auto-escaping rules apply to all user-influenced fields?
- Are URL contexts using percent-encoding, not HTML entities alone?
- Is JSON-LD escaped with JSON rules, not HTML entity rules?
- Do tests include malicious strings with &, quotes, and angle brackets?
Hands-on project
Build encoding test suite for a CMS template — fixtures with &, <, unicode, emoji; verify HTML output, JSON-LD sidecar, and URL query encoding; document context matrix in README.
- Deliverable: Context encoding table + automated tests.
- Verify: OWASP ZAP passive scan on rendered pages.
- Stretch: Fix double-encoding bug in legacy template path.
Interview questions
Difference between HTML entity encoding, URL encoding, and JavaScript string escaping?(Advanced)
HTML entities (<, &) for HTML text/attribute parse safety. URL encoding (%26, %20) for URL components per RFC 3986. JS escaping (\u, \x) for script string literals. Wrong context encoding fails XSS defense — attribute HTML-encoded then put in JS without JS escape still vulnerable.
Follow-up: Where does CSS encoding fit?
UTF-8 vs HTML entities for international product names on Amazon-scale catalog?(Advanced)
Store and transmit UTF-8; meta charset utf-8; encode only syntactic characters (& < > quotes in attrs) on HTML output. Numeric entities for every CJK character bloat HTML unnecessarily. Ensure database, API, HTML pipeline charset end-to-end consistent.
Follow-up: What if legacy system is Latin-1?
How do double-encoding bugs manifest and how to detect in CI?(Advanced)
User sees & or &amp; literally. Caused by multiple escape passes or decode-then-escape order wrong. CI snapshot tests with & in input; grep output for &amp; patterns; fuzz template with entity-heavy strings. Monitor support tickets for 'weird symbols on site'.
Follow-up: Entity in SVG inline?
Try it yourself
Edit the HTML, CSS, or JS panels — the preview updates as you type.
Try it yourself
Summary
HTML entities escape syntactically significant characters and represent symbols in markup. Production pipelines at Shopify and Stripe encode on output per context with UTF-8 documents — entity mistakes break parsing, display, and security simultaneously.