About String Escape & Unescape Tool
String Escape & Unescape Tool rewrites a value so that a JSON parser, a JavaScript compiler, an HTML parser, or a URL parser reads it as data instead of as syntax. Pick one of the four target contexts, choose escape or unescape, and the result pane shows exactly which characters were rewritten and which were left alone.
Escaping is not one operation with one correct answer. The same string needs a backslash before a double quote in JSON, a backslash before a single quote in a JavaScript literal, an entity reference in HTML, and a percent sequence in a query string. A result that is correct for one of those four is wrong — occasionally dangerously wrong — in the other three. The question is never "how do I escape this"; it is "which parser reads this value first".
How to use this developer tool
- Decide where the value will land: inside a JSON string, inside a JavaScript string literal, inside HTML text or an attribute, or inside one component of a URL.
- Select that context in the rule list and set the mode switch to Escape or Unescape.
- Paste one representative value rather than an entire document, then run the conversion.
- Compare the two panes at the delimiters. Quotes, backslashes, angle brackets, percent signs, and line breaks are the only places the four contexts disagree.
- Copy the result and let the real parser confirm it: feed a JSON result to the JSON Formatter, or send a URL result in an actual request instead of trusting a visual check.
Worked example: one value, four correct answers
This value carries the four characters the contexts disagree about: a single quote, a double quote, a backslash, and a line break. Running it through each rule in turn makes the differences impossible to miss.
O'Neill & Sons said "ok"
path: C:\tmp\a b.txtJSON string
O'Neill & Sons said \"ok\"\npath: C:\\tmp\\a b.txt
JavaScript string
O\'Neill & Sons said \"ok\"\npath: C:\\tmp\\a b.txt
HTML entities
O'Neill & Sons said "ok"
path: C:\tmp\a b.txt
URL component
O'Neill%20%26%20Sons%20said%20%22ok%22%0Apath%3A%20C%3A%5Ctmp%5Ca%20b.txtThree details are worth stopping on. JSON leaves the single quote untouched while JavaScript escapes it. HTML leaves the backslash and the real line break untouched, because neither means anything to an HTML parser. And the URL rule also leaves the single quote alone, which is why a percent-encoded value is still not safe to drop into a single-quoted attribute.
The same character in each target context
Read across a row to see why a value escaped for one context is not escaped for another. "Unchanged" means the character is copied through byte for byte.
| Character | JSON string | JavaScript string | HTML entities | URL component |
|---|---|---|---|---|
| Double quote | \" | \" | " | %22 |
| Single quote | unchanged | \' | ' | unchanged |
| Backslash | \\ | \\ | unchanged | %5C |
| Line break | \n | \n | unchanged, stays a real newline | %0A |
| Ampersand | unchanged | unchanged | & | %26 |
| Less-than | unchanged | unchanged | < | %3C |
| NUL, U+0000 | \u0000 | left as a raw control character | left as a raw control character | %00 |
| Any non-ASCII character | unchanged | unchanged | unchanged | %E4%B8%AD for 中 |
Troubleshooting
The output has twice as many backslashes as expected.
Why it happens The value was already escaped once. Escaping it again escapes the backslashes that the first pass introduced, so a JSON fragment reading \"ok\" becomes \\\"ok\\\".
Fix Switch to Unescape, run it once, and confirm the input pane now shows the plain original. Escape once from there. If two rounds of unescaping are needed, the value really was double-encoded upstream and that is the bug to fix.
The value is escaped and the page still breaks.
Why it happens It was escaped for the wrong context. URL encoding does not touch the single quote, so a percent-encoded value placed inside a single-quoted HTML attribute still closes the attribute early.
Fix Escape for the innermost parser first, then for each enclosing one, in that order. Never substitute one context's rules for another's because the output happens to look encoded.
URL escape fails on a value containing an emoji or another non-BMP character.
Why it happens Characters above U+FFFF are stored as a surrogate pair. If the value was trimmed with slice or substring at a fixed length, the pair can be split, and percent encoding refuses a lone surrogate half.
Fix Cut strings on code-point boundaries, for example by spreading into an array first, rather than on UTF-16 indices. Note that JSON mode does not fail here — it emits \ud83d for the orphaned half — so the same defect stays invisible if you only test the JSON path.
JavaScript unescape turns a Windows path into a tab and a newline.
Why it happens The JavaScript rule expands the two-character sequences for newline, carriage return, and tab before it collapses doubled backslashes, so in C:\\tmp\\new.txt the second backslash pairs with the following letter.
Fix Use the JSON rule for anything that contains doubled backslashes; a JSON parser resolves the ordering correctly. Reserve the JavaScript rule for short literals that contain quotes but no escaped path separators.
When this tool is the right choice
- Folding a multi-line snippet — a certificate body, a log excerpt, a shell script — into a single JSON string field.
- Working out why a query-string value arrives truncated by seeing which characters were never percent-encoded.
- Reading an over-escaped value out of a log line where a JSON document was serialized into another JSON string.
- Turning a block of user-supplied text into HTML-safe content for a test fixture or a snapshot file.
When to use something else
- Making untrusted input safe. Escaping changes representation, not meaning; a string escaped for HTML is still whatever it was, and a template that inserts it unescaped later undoes the work.
- Encoding a complete URL. The URL rule escapes one component, so it also encodes the slashes, colons, and question marks a full address needs. Use the URL Encoder & Decoder for a whole address.
- Bulk entity work across an HTML document. The HTML Entity Encoder & Decoder handles that and covers named entities beyond the five characters this rule rewrites.
Privacy and data handling
Every conversion runs in this browser tab using the platform's own JSON.stringify, encodeURIComponent, and DOM APIs. Nothing is uploaded and nothing survives the tab closing. The values people escape are frequently the sensitive ones — a connection string, a signed URL, a bearer token — so replace those with placeholders of the same shape first. Local processing keeps the value off our servers, not away from a browser extension.
Related developer tools
Frequently asked questions
Why does JSON mode leave the single quote alone?
The JSON grammar only requires escapes for the double quote, the backslash, and control characters below U+0020. A single quote carries no meaning inside a JSON string, so it is copied through. JavaScript mode escapes it because a JavaScript literal can be delimited by single quotes.
Is escaping the same as sanitizing?
No. Escaping guarantees that a parser reads your value as one opaque token. Sanitizing decides which content is allowed at all. A comment body escaped for HTML renders as harmless text, but the same body is still unsafe if another part of the system renders it as markup.
Why does the HTML result still contain line breaks?
HTML entity escaping only rewrites the five characters that have structural meaning. A newline is ordinary whitespace to an HTML parser and is collapsed at render time, not removed. If you need the breaks to show, wrap the value in a pre element or set white-space to pre-wrap.
Does escaping change the meaning of my value?
Not if you apply exactly one round trip. Escape then unescape with the same rule returns the original string in every context here, with one exception worth remembering: the JavaScript rule is lossy for doubled backslashes, so it does not round-trip Windows paths.
Which rule should I use for a shell command or a regular expression?
None of these four. A shell has its own metacharacters and quoting rules, and a regular expression has a different set again. Build the pattern in the Regular Expression Tester, and quote shell arguments with your language's own argument-array API instead of string concatenation.
Why does the tool ask for a small representative value instead of the whole file?
Escaping is context-sensitive, and a whole file usually spans several contexts: a JSON document containing an HTML fragment containing a URL. Escaping the file as one unit applies the wrong rule to most of it. Convert the single value that crosses a boundary and leave the rest alone.