ToolNest logoToolNest.

How to Encode HTML Special Characters Online

To encode HTML special characters, replace each reserved character with its entity: & becomes &amp;, < becomes &lt;, > becomes &gt;, and quotes become &quot; or &#39;. This tells the browser to display the character instead of treating it as markup. Do it in one click with ToolNest's free HTML encoder — it runs in your browser, so your text is never uploaded.

The five characters that must be encoded

HTML reserves a small set of characters for its own syntax, and any literal use of them in text is ambiguous to the parser. The mandatory five: & (starts an entity — an unencoded & followed by text can be misread as one), < (starts a tag — a literal <div> in your article becomes an actual div), > (ends a tag), " (delimits attribute values), and ' (the apostrophe, which breaks single-quoted attributes and JavaScript strings). Encoding swaps each for an entity reference: &amp;, &lt;, &gt;, &quot;, &#39;. The browser renders the original character; the parser never mistakes it for markup. In practice, encoding &, <, and > covers nearly every real-world case — quotes matter mainly inside attribute values and inline scripts. If you write tutorials that show code samples (like this article does), encoding is not optional: it's the difference between displaying <div> and rendering an empty div.

Named, decimal, and hex entities

Every encodable character has up to three entity forms. Named entities are mnemonic: &amp; &lt; &gt; &quot; &copy; &nbsp;. Decimal numeric entities use the Unicode code point: &#38; &#60; &#62; &#34; &#169;. Hexadecimal numeric entities do the same in base 16: &#x26; &#x3C; &#x3E; &#x22; &#xA9;. All three render identically — browsers resolve them to the same character. Named entities win on readability (&copy; obviously means ©), but only about 250 characters have names; numeric entities cover the entire Unicode range, so an emoji or a rare symbol must go numeric (😀). One special case deserves attention: &nbsp;, the non-breaking space. It looks like a space but glues words together across line breaks — useful for '100 km' or brand names, and a classic culprit when copied text won't match in find-and-replace.

When encoding is actually required

Encode whenever untrusted or literal text meets an HTML context. User-generated content — comments, usernames, form input echoed back to a page — is the canonical case: encoding the five reserved characters neutralizes the standard cross-site scripting (XSS) payload, because <script> arrives as inert text instead of an executable tag. (Encoding is necessary but not sufficient for full XSS defense — context-aware output encoding plus Content Security Policy is the complete answer.) CMS and blog editors in 'text/code' mode: pasting raw HTML samples without encoding makes the editor swallow them as live markup. Email templates, where some clients parse aggressively. Code documentation and tutorials — every code block on this page went through encoding. What does not need encoding: text inside a properly built DOM (setting textContent handles it), JSON payloads (JSON has its own escaping — see our what-is-JSON guide), and URLs (which use percent-encoding instead — our URL encoding guide covers that separate system).

The double-encoding trap

The most common encoding bug is encoding twice. It happens like this: your CMS encodes < into &lt; on save, then your template engine encodes again on render, turning it into &amp;lt; — and visitors see the literal text '&lt;' instead of '<'. The rule: encode exactly once, at the boundary where text enters HTML. Store the raw text; encode on output. If you're seeing entities displayed as text, something encoded twice — decode once (or find which layer is double-processing). The reverse bug also exists: decoding user input before storing it, then rendering it raw — that un-encodes the protection. A quick diagnostic: view the page source. If you see &amp;lt; in the source where you expected &lt;, that's double encoding. If you see a raw <script> in source from user input, that's missing encoding — fix it before anything else.

Encoding in code: JavaScript, Python, PHP

You rarely need to hand-roll the replacements — every language ships the function. In JavaScript, the safest path avoids manual encoding entirely: assign to textContent instead of innerHTML, and the DOM encodes for you. If you must produce an encoded string (an email body, an RSS feed), the standard trick is: const el = document.createElement('div'); el.textContent = raw; const encoded = el.innerHTML. In Python, html.escape(text) encodes &, <, >, and optionally quotes (quote=True is the default and the right choice). In PHP, htmlspecialchars($text, ENT_QUOTES, 'UTF-8') does the same. The manual-replace approach (text.replace(/&/g, '&amp;').replace(/</g, '&lt;')…) works only if you replace & first — doing it last re-encodes the ampersands you just introduced, manufacturing the double-encoding bug by hand. Prefer the standard library; it also handles edge cases (like astral-plane characters) that regexes miss.

HTML encoding vs URL encoding vs Base64

Three encodings, three jobs — mixing them up is a rite of passage. HTML encoding (this article) protects text inside HTML documents: < becomes &lt;. URL/percent-encoding makes text safe inside URLs: a space becomes %20, & becomes %26 — see our URL encoding guide for the full chart and the reserved-vs-unreserved rules. Base64 represents binary data as ASCII text (images in data URIs, binary blobs in JSON) — it's a transport encoding, not an escaping mechanism; our Base64 guide explains when it applies. The decision tree: putting text into HTML? HTML-encode. Putting text into a URL? Percent-encode. Moving binary through a text channel? Base64. Applying the wrong one is a real bug class — HTML-encoding a URL leaves the & in query strings unencoded (breaking parameters), while percent-encoding HTML shows visitors literal %3C text.

The one-click method

For ad-hoc work — a code sample for a blog post, a snippet for a template, a chunk of text that keeps rendering as markup — manual entity replacement is slow and error-prone. Paste the text into ToolNest's free HTML encoder, copy the encoded output, and paste it where the HTML goes. It encodes the full reserved set (with named entities where they exist), runs entirely in your browser so nothing is uploaded, and the matching decoder reverses the process when you need the original back. Pair it with the companion guides when the job crosses boundaries: URL-encode for links and query strings, JSON escaping for API payloads.

Do it in one click

Encode HTML special characters instantly — entities, named and numeric, with a matching decoder. Free, no signup.

Open the Free Tool →