Encode & Decode
URL Encoding Explained: Percent-Encode Query Strings Without Breaking Them
Understand percent-encoding, when to use encodeURIComponent vs encodeURI, and how to safely encode and decode query-string values and URLs in the browser.
Try the toolURL Encode / Decode →You build a URL by concatenating a value into a query string, and suddenly a link is truncated, a search fails, or a redirect drops half its parameters. The usual culprit is an un-encoded character: an ampersand, a space, a slash, or a plus sign that means something structural in a URL. Percent-encoding is how you escape those characters so they travel as data instead of syntax.
What percent-encoding is
URLs are limited to a small set of ASCII characters. Anything reserved (& = ? / # : @ + and others) or unsafe (spaces, non-ASCII, most punctuation) gets replaced by % followed by the byte's two-digit hex value. A space becomes %20, an ampersand becomes %26, and a forward slash becomes %2F. On decode, each %XX is turned back into its original character.
The distinction that trips everyone up
JavaScript ships two encoders, and picking the wrong one is the most common mistake:
encodeURIComponent()encodes almost everything, including&,=,?, and/. Use it for a single value — one query parameter, one path segment.encodeURI()leaves the structural characters intact so a whole URL stays functional. Use it for an entire URL, never for one field.
Watch the difference on the same input:
const value = 'a b&c=d?e/f';
encodeURIComponent(value);
// "a%20b%26c%3Dd%3Fe%2Ff" ← every reserved char escaped
encodeURI('https://x.com/a b?q=1&2');
// "https://x.com/a%20b?q=1&2" ← ? & / preserved
The rule: if you're inserting user input into one slot of a URL, reach for encodeURIComponent. If you get it backwards, the & inside a value will be read as a parameter separator and your data splits apart.
A practical walkthrough
Say you want to link to a search for the phrase tom & jerry plus a redirect back to /home?tab=1. Encode each value separately:
const q = encodeURIComponent('tom & jerry'); // "tom%20%26%20jerry"
const back = encodeURIComponent('/home?tab=1'); // "%2Fhome%3Ftab%3D1"
const url = `https://site.com/search?q=${q}&return=${back}`;
// https://site.com/search?q=tom%20%26%20jerry&return=%2Fhome%3Ftab%3D1
Now the ampersand and the nested query string live safely inside their parameters. Paste any URL into the URL Encode / Decode tool to encode or decode it instantly in your browser — nothing is sent to a server, which matters when the string contains tokens or personal data.
Common pitfalls
The+sign is the classic gotcha. In the query part of a URL,+historically means a space.
- Plus vs space.
decodeURIComponent('a%2Bb')returnsa+b, butdecodeURIComponent('a+b')returnsa+bunchanged — it does not turn+into a space. Form submissions (application/x-www-form-urlencoded) do treat+as a space, so decode those with that rule in mind. - Double-encoding. Encoding an already-encoded string turns
%20into%2520. Decode once before re-encoding, and never run a full URL throughencodeURIComponent. - Non-ASCII is multi-byte. Modern encoders use UTF-8, so an emoji or accented letter becomes several
%XXpairs. That's correct — don't try to hand-fix it. - Hash fragments. The part after
#never reaches the server, so encode it only if the client-side router needs it clean.
Related tools
Once a URL is assembled, split it apart with the URL Parser to verify each parameter decoded the way you expected. If you're escaping strings for HTML rather than URLs, the HTML Entity Encoder handles that separate escaping context.
Conclusion
Percent-encoding is simple once you internalize the split: encode whole URLs with one tool, encode individual values with another, and remember that reserved characters inside a value must be escaped or they'll be read as structure. Encode each value separately, decode exactly once, and mind the + sign, and your query strings will stop mysteriously breaking.