Encode and decode URLs the right way. Toggle between encodeURIComponent, encodeURI, and form-style + encoding — and see a per-character diff of exactly what changed. Fully client-side.
?q=<value>.
Takes any text — a URL, a query-string value, a search string, an email, a path with spaces — and either percent-encodes it for safe transport in a URL, or decodes an already-encoded string back to plain text. All three JavaScript encoding modes are supported so you can pick the one that matches your context, and a per-character diff shows you exactly which bytes changed and why.
encodeURIComponent — encodes every reserved URI character. Use it when the value goes inside a URL (query-string values, path segments, form fields). This is the safest default.encodeURI — preserves reserved characters that have structural meaning in a URL (/, :, ?, #, &, =, +, ,, ;, @). Use it on a whole URL that just needs its illegal characters (spaces, quotes, non-ASCII) escaped.encodeURIComponent, but replaces %20 with +. Matches the historical application/x-www-form-urlencoded behavior HTML forms produce.Percent-encoding bugs are notoriously hard to spot because a "wrong" URL often looks fine at a glance. The diff shows every character that got encoded, its output bytes, and its Unicode code point — so you can immediately answer questions like "did the + get encoded or not?", "is this really a space or a non-breaking space?", and "why is one URL 8 bytes longer than another?"
Percent-encoding replaces each byte that's reserved, unsafe, or non-ASCII with a % followed by two uppercase hex digits. For characters outside the ASCII range, the character is first encoded as UTF-8 and each of those bytes is percent-encoded individually. So é (U+00E9) becomes %C3%A9, and the pile-of-poo emoji 💩 (U+1F4A9, four UTF-8 bytes) becomes %F0%9F%92%A9.
The unreserved character set that never needs encoding is: A-Z a-z 0-9 - _ . ~. Everything else gets encoded by encodeURIComponent; encodeURI additionally preserves the reserved delimiters listed above so that a URL remains parseable after encoding.
encodeURI for a query-string value. It leaves & and = unencoded, which merges your value into the outer query string. Always use encodeURIComponent for values.+ means space. Only true inside form-encoded query strings. In a URL path, + is a literal plus sign.encodeURIComponent again turns %20 into %2520. This is one of the most common causes of "why does my URL have %25 everywhere?"# in a value. A stray # silently truncates the URL at the fragment boundary. The browser will not include anything after it in the request.URLSearchParams. The URLSearchParams API in modern browsers does encoding for you and is much harder to get wrong than manual string building.For the canonical rules, the RFC 3986 URI generic syntax and the current WHATWG URL Standard are the definitive references.
Browse backend, platform, and developer-tools engineering roles across 100+ companies profiled with real culture data.
Browse Engineering Jobs → Portfolio project ideas →encodeURIComponent encodes every reserved URI character (including /, :, ?, #, &, =, +) because it assumes the input is a single query-string value or path segment that will be embedded inside a URL. encodeURI is meant for a full URL and deliberately preserves reserved characters that have structural meaning (/, :, ?, #, &, =, +, ,, ;, @) so the URL remains parseable. Rule of thumb: use encodeURIComponent for values you put into query strings and path segments; use encodeURI only when you have an already-formed URL that just needs its illegal characters escaped.%20 is the standard percent-encoding of a space and is valid anywhere in a URL. + only means space inside the query string of an application/x-www-form-urlencoded body or query, which is what HTML forms produce by default. Using + in a URL path is wrong — it will not be decoded to a space. If you're not sure, use %20; it is always safe. Pick the form-style mode in this tool when you specifically need HTML-form-compatible encoding.encodeURIComponent, encodeURI, and decodeURIComponent functions. The tool makes no network requests with your input, does not log it, and does not store it anywhere. You can verify by opening the browser DevTools Network tab while you use the tool — you will see no outbound requests carrying your text. That said, URLs frequently contain secrets (tokens, session IDs); if a URL is sensitive, treat any tool you paste it into with appropriate care and rotate the secret afterwards if in doubt.decodeURIComponent throws a URIError when it encounters a % sign that is not followed by two valid hex digits, or when the resulting bytes are not valid UTF-8. The most common causes are: (1) a raw % that was meant to be literal but was never encoded (should be %25), (2) truncated input where the last percent-escape is cut off (e.g. %E4%B8 missing its third byte), (3) mixed encoding where part of the string is double-encoded and part is not, and (4) input that was encoded as a different charset (Latin-1, Shift-JIS). Look for stray % characters, and if you know the input was double-encoded, decode twice.redirect_uri that itself contains query parameters must be encoded once so its & and = do not merge with the outer query string. If you naively encode https://example.com/callback?state=xyz once, an intermediate proxy or your own server-side URL parser might unpack it prematurely. Double-encoding — encoding the whole encoded string a second time — ensures the intended layer sees the correctly-encoded value. Most of the time you do NOT want double encoding; if you're passing a value between systems, encode exactly once at each boundary.? and #), unsafe (would confuse older systems, like space and quote), or non-ASCII. Each byte is replaced with a % followed by two uppercase hex digits, for example space becomes %20 and é (which is two UTF-8 bytes: 0xC3 0xA9) becomes %C3%A9. Modern browsers and JavaScript's built-in functions always use UTF-8 for multi-byte characters, which matches the current WHATWG URL Standard.