URL Encoder: Fix Your Broken Query Strings
URLs can only contain a small set of ASCII characters. Spaces, ampersands, Unicode — everything else needs to be encoded or the URL breaks. A space becomes %20. An ampersand becomes %26. That ü in someone's name becomes %C3%BC.
Without encoding, https://example.com/search?q=Tom & Jerry is ambiguous — is & part of the query value or a parameter separator? The URL encoder answers that question by escaping everything that needs escaping.
This tool encodes and decodes URL strings instantly. Paste encoded garbage from a log file and see what it actually says. Or paste plain text and get the encoded version. No signup, no install.
What's actually happening
Percent-encoding replaces each unsafe byte with % followed by its two-digit hex value. The @ character is hex 40, so it encodes as %40. Multi-byte UTF-8 characters produce multiple triplets: € (3 bytes in UTF-8) becomes %E2%82%AC.
Characters fall into two buckets:
Unreserved — never encoded: A-Z a-z 0-9 - _ . ~
Reserved — have structural meaning in URLs and must be encoded when used as data:
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
Spaces are a special case. %20 is the universal encoding. + also represents a space, but only in query strings (from the application/x-www-form-urlencoded spec). In path segments, + is a literal plus sign.
Using it
Pick Encode or Decode. Paste your input. Output updates automatically. Hit Copy.
When you'd actually reach for this
- You're building a URL with query parameters that contain user input — names, search terms, addresses
- You need a redirect URL with nested query strings:
?redirect=https%3A%2F%2Fexample.com%2Fcallback%3Ftoken%3Dabc - You're encoding filenames with spaces for download links —
my%20report.pdfinstead of a broken link - You're debugging encoded URLs from server logs or analytics — decoding
%2Fback to/to understand the original request - You're constructing OAuth authorization URLs with encoded
redirect_uri,scope, andstateparameters
encodeURI vs encodeURIComponent — the one JavaScript quirk everyone gets wrong
JavaScript gives you two functions and the names barely help.
encodeURI() — for encoding a complete URL. Leaves structural characters (:, /, ?, #, &) alone because they're part of URL syntax:
encodeURI('https://example.com/path?q=hello world')
// → 'https://example.com/path?q=hello%20world'
encodeURIComponent() — for encoding a single value (like a query parameter). Encodes everything except unreserved characters:
encodeURIComponent('hello world&more')
// → 'hello%20world%26more'
Rule of thumb: encodeURIComponent() for individual parameter values. encodeURI() only when you have a full, already-structured URL. In practice, encodeURIComponent() is what you want 90% of the time.
The classic mistake — encoding a full URL with encodeURIComponent():
encodeURIComponent('https://example.com/path')
// → 'https%3A%2F%2Fexample.com%2Fpath' ← broken URL
Seen this in production. More than once.
Troubleshooting
My URL has %252F instead of %2F — it's been double-encoded. %25 is the encoding of % itself. Your code is encoding an already-encoded string. Decode once to get %2F, decode again to get /. Find where the double encoding happens and fix it.
Spaces show as + in some places and %20 in others — both are valid, but in different contexts. + is only valid in query strings (HTML form encoding). %20 works everywhere. If you need consistency, use %20.
I encoded a full URL and now the slashes are gone — you used encodeURIComponent() on the whole URL instead of just the parameter values. Use encodeURI() for full URLs, or better, build the URL piece by piece with encodeURIComponent() on each value.
Non-ASCII characters aren't encoding correctly — make sure your input is UTF-8. URL encoding operates on bytes, not characters. UTF-8 ü is 2 bytes → %C3%BC. If your system uses a different encoding, the percent-encoded bytes will differ.
My decoded URL still has encoded characters — some characters are legitimately part of the URL structure and shouldn't be decoded. %2F in a path parameter is intentionally a literal slash encoded to avoid being interpreted as a path separator.
What to do with the result
If you encoded something, paste it into your URL. If you decoded something, now you can read it.
For building URLs in code, use your language's URL builder instead of string concatenation:
- JavaScript:
new URL()+URLSearchParams - Python:
urllib.parse.urlencode() - Go:
url.QueryEscape()
String concatenation with manual encoding is how double-encoding bugs happen.
One more thing: if you're debugging URL issues in production, check your web server's access logs. Most servers log the decoded URL, but some log the raw encoded version. Knowing which format you're looking at saves a lot of confusion when /api/users%2F123 and /api/users/123 hit different routes.