Percent encoding, without guesswork
URL Encoder & Decoder
Choose the syntax you actually have, transform one layer at a time, and see strict malformed-escape and UTF-8 errors. Text stays in this browser tab.
Transform text
URI component: uses JavaScript component semantics. Delimiters such as /, ?, &, =, and # are data and will be encoded.
Maximum 50,000 UTF-16 code units and 100,000 UTF-8 bytes. Decode validates every percent escape and UTF-8 byte sequence before changing the output. Error positions are 1-based Unicode characters, not UTF-16 offsets.
Result
No result yet. Each Decode action removes exactly one encoding layer.
Parsed query pairs
Query pairs will appear here.
| # | Name | Value |
|---|---|---|
| No pairs parsed. | ||
Pick the correct context
Component
Use for one path segment, query name, query value, or fragment value. A literal slash or ampersand is data here, so component encoding escapes it.
Complete URL
Uses encodeURI/decodeURI semantics and preserves structural delimiters. It does not validate a hostname, normalize a path, convert an internationalized domain, or make an unsafe scheme trustworthy.
Form value
Uses the application/x-www-form-urlencoded percent-encode set. A space becomes +; a literal plus becomes %2B. Decode therefore treats raw + as a space only in form and query modes.
Structured query mode
Query Encode expects a JSON array of string pairs, for example [["tag","a+b"],["tag","x&y"]]. Query Decode accepts an optional leading ? and returns that same unambiguous pair-array shape.
This preserves repeated names, order, empty names and values, plus signs, ampersands, equals signs, and Unicode without asking you to guess which visible delimiter is data. Encoding produces the canonical URLSearchParams string without a leading question mark. Decoding normalizes away empty separator segments such as a trailing &.
At most 200 pairs are accepted, and the on-page inspector shows at most the first 50.
Errors, repetition, and privacy
- A percent sign must have two hexadecimal digits. Percent bytes must form scalar UTF-8, not overlong, truncated, surrogate, or out-of-range sequences.
- Decode runs once. For
%2520, the first result is%20; swap and decode again only if another layer is intentional. Encode treats an existing percent sign as data and escapes it again. - This tool is strict even though
URLSearchParamsparsing in browsers is forgiving. Strict rejection prevents malformed bytes from silently becoming replacement characters. - Everything runs locally. No input, result, request, upload, cookie, or browser storage is created by this tool. Shared page analytics cannot read these fields.