HTML entity encode/decode · Guide

How to Escape HTML Online Without Double-Encoding It

Escaping HTML converts characters with syntactic meaning into character references so a browser displays them as text instead of parsing them as markup. Paste raw text into the encoder, copy the escaped result, and use it only where HTML text or a quoted attribute is expected. The security-critical detail is context: HTML escaping does not make a value safe inside JavaScript, CSS or a URL, and pre-escaped data passed through an auto-escaping template becomes visibly double-encoded.

The five characters that matter most

The core HTML characters are ampersand, less-than, greater-than, double quote and single quote. Ampersand begins a character reference; less-than begins a tag; quotes can close a matching quoted attribute. Greater-than is often harmless in text but escaping it keeps encoded fragments consistent.

Text
Character   Escaped HTML
&           &
<           &lt;
>           &gt;
"           &quot;
'           &#039;  or &apos; in modern HTML

After parsing, each reference becomes the original character in the DOM. Escaped output is a representation for source code, not a different value. A user sees <admin> while View Source contains &lt;admin&gt;.

Use UTF-8 directly for ordinary letters, accented text and emoji. You do not need to replace every non-ASCII character with a numeric entity; doing so reduces readability without adding safety.

Escape at the final HTML output boundary

Keep application and database values raw, then escape when rendering them into HTML. This gives each destination the correct representation and avoids records that are sometimes raw and sometimes encoded.

JavaScript
const raw = '<img src=x onerror=alert(1)>';
const output = document.querySelector('#output');
output.textContent = raw; // displayed as text, no HTML execution

// Avoid: output.innerHTML = raw;

DOM textContent already treats its value as text. Do not HTML-escape before assigning it, or the user will see literal &lt;. Similarly, modern template engines normally escape interpolated values; pass raw text through their standard interpolation rather than marking it as trusted HTML.

Escaping on input is fragile because the same value may later be used in JSON, email text or a URL. Store meaning, not one presentation layer. Validate input for business rules, but encode it for the destination on output.

Text and quoted attributes need slightly different care

Escaping <, > and & is sufficient for normal text parsing, while quoted attributes must also escape the quote used as delimiter. Encoding both quote types is a safe default when one encoder handles text and attributes.

HTML
<!-- Raw value: She said "yes" & left -->
<div title="She said &quot;yes&quot; &amp; left">Example</div>

<!-- Always quote attributes; unquoted syntax has more delimiters. -->

Never build attribute names or tag names from untrusted input. Encoding a value protects a value position; it cannot make onclick, style or an arbitrary element name safe. Allow-list structural choices in code.

URL-valued attributes require two layers. Encode individual URL components first, assemble the URL, then HTML-escape the complete attribute. An ampersand inside query data becomes %26; an ampersand separating pairs appears as &amp; in HTML source.

Avoid double encoding and incorrect decoding

Encoding &lt; again produces &amp;lt;. The browser decodes one layer and displays &lt; instead of <. Unexpected &amp; text is therefore evidence that encoded content crossed another escaping boundary.

Text
raw:           Tom & Jerry
escaped once:  Tom &amp; Jerry
escaped twice: Tom &amp;amp; Jerry
visible after parsing twice-escaped source: Tom &amp; Jerry

Do not fix double encoding by globally decoding every value. A string may legitimately contain text that resembles an entity, and decoding user-controlled data before assigning innerHTML can reactivate markup. Fix ownership so exactly one renderer encodes raw data.

When migrating pre-escaped database rows, identify them from provenance rather than merely searching for &. Decode with a real HTML entity decoder, review ambiguous records, and make writers follow one storage contract.

Use standard server-side encoders

A library encoder handles replacement order, quote modes and invalid byte sequences. Manual calls such as replace('<', '&lt;') routinely forget ampersands or attributes and may double-encode references created by earlier replacements.

PHP
$raw = '5 < 8 & "quoted"';
$safe = htmlspecialchars(
    $raw,
    ENT_QUOTES | ENT_SUBSTITUTE,
    'UTF-8'
);
echo $safe;
// 5 &lt; 8 &amp; &quot;quoted&quot;
Python
from html import escape

raw = '5 < 8 & "quoted"'
print(escape(raw, quote=True))
# 5 &lt; 8 &amp; &quot;quoted&quot;

Set the character encoding explicitly and keep the response header consistent with it. Invalid UTF-8 should be rejected or substituted deliberately rather than making the encoder return surprising empty output.

HTML escaping is not universal output encoding

A value inside a JavaScript string is parsed by JavaScript after the HTML parser. Inside a style attribute it reaches CSS; inside an href it reaches a URL parser. Each grammar has different delimiters, so HTML entities alone cannot provide the next layer's safety.

HTML
<!-- Prefer serialised data and separate code. -->
<div id="profile" data-name="Ada &amp; Co"></div>
<script src="/profile.js"></script>

<!-- Avoid concatenating data into inline script or event handlers. -->

For JavaScript data, serialise with a JSON encoder and deliver it in a safe data channel. For URLs, use a URL builder and restrict dangerous schemes such as javascript:. For CSS, avoid dynamic source where possible and allow-list expected values.

Escaping also differs from sanitising. Escaping displays markup characters as text. Sanitising parses intended HTML and removes forbidden elements, attributes and URLs. If users are allowed rich text, use a maintained HTML sanitiser with an explicit policy rather than decoding escaped input.

Verify escaped output online

Before pasting text into an online encoder, remove secrets, tokens and personal data because an external service may receive or log input. A client-side tool that processes locally reduces exposure, but browser extensions and device policies still apply.

Text
Input:  <strong title="A & B">hello</strong>
Output: &lt;strong title=&quot;A &amp; B&quot;&gt;hello&lt;/strong&gt;

Expected visible text after HTML parsing:
<strong title="A & B">hello</strong>

Verify three views: the encoded string should contain entities, the rendered page should display the original characters as text, and the DOM inspector should show a text node rather than a new element. Test ampersand and both quote types, not only angle brackets.

If the destination is an auto-escaping template, the correct input is usually the original raw string rather than the tool's encoded result. Online escaping is most useful when producing a literal documentation example, static HTML source or diagnosing exactly which representation a layer expects.

Frequently asked questions

How do I escape HTML?

Convert HTML syntax characters with a standard encoder at the point where raw data enters HTML text or a quoted attribute. The main mappings are & to &amp;, < to &lt;, > to &gt;, and quotes to their references.

Which characters need escaping in HTML?

Always handle ampersand and less-than in text. In quoted attributes, also escape the matching quote; encoding both quote types and greater-than is a practical safe default for a general HTML encoder.

Why do I see &amp; or &lt; on the page?

The value was likely escaped twice or assigned as text after being pre-escaped. Keep the stored value raw and let exactly one final HTML renderer encode it.

Is HTML escaping enough to prevent XSS?

Only when untrusted data is inserted into an HTML text or properly quoted attribute-value context. JavaScript, CSS, URLs and structural markup need different handling; use safe APIs and allow-lists rather than moving escaped text between contexts.

What is the difference between escaping and sanitising HTML?

Escaping makes all markup display as text. Sanitising allows selected markup after parsing it and removes disallowed elements, attributes and URLs. Rich user HTML needs a maintained sanitiser, not a chain of replacements.

Should I store escaped HTML in the database?

Usually no. Store raw application data and escape for each output context when rendering. Pre-escaped storage causes double encoding and makes non-HTML outputs incorrect.

Ready to try it?

Open the free browser-based HTML entity encode/decode and apply what you just read — no sign-up, runs locally.

Open the HTML entity encode/decode tool