DEV Community

ZahrionTech
ZahrionTech

Posted on

URL Encoding Explained: encodeURIComponent vs encodeURI (and a Free Online Tool)

Every developer building URLs from user input eventually meets percent-encoding: spaces become %20, ampersands become %26, and so on. JavaScript gives you two built-in functions for this — encodeURIComponent and encodeURI — and mixing them up is one of the most common sources of broken links and double-encoded query strings. Let's sort it out.

What URL encoding actually does

URLs may only contain a limited set of characters. Everything else must be percent-encoded: replaced with % followed by its UTF-8 byte values in hexadecimal. For example:

  • a space becomes %20
  • & becomes %26
  • ? becomes %3F
  • é becomes %C3%A9

JavaScript performs this for you with two global functions.

encodeURIComponent — for a single piece of a URL

encodeURIComponent() escapes everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ). It's designed for encoding one value — a query parameter, a path segment, a fragment — before you drop it into a URL:

const search = "hello world & goodbye";
const url = `https://example.com/search?q=${encodeURIComponent(search)}`;
console.log(url);
// https://example.com/search?q=hello%20world%20%26%20goodbye
Enter fullscreen mode Exit fullscreen mode

Note how the & inside the value is encoded to %26, so it can't be mistaken for a parameter separator.

encodeURI — for a whole URL

encodeURI() is meant for encoding an entire URI. It leaves the reserved characters that give a URL its structure untouched — ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) # — and only encodes things like spaces and non-ASCII characters:

encodeURI("https://example.com/a b?x=1&y=2");
// "https://example.com/a%20b?x=1&y=2"
Enter fullscreen mode Exit fullscreen mode

The space is fixed, but ?, &, and = keep working as URL syntax.

The rule of thumb

Situation Use
Encoding one query parameter or path segment encodeURIComponent
Encoding a full URL that already has structure encodeURI
Decoding them back decodeURIComponent / decodeURI

The classic mistake is encoding a whole URL with encodeURIComponent:

encodeURIComponent("https://example.com/?q=a b");
// "https%3A%2F%2Fexample.com%2F%3Fq%3Da%20b" — broken!
Enter fullscreen mode Exit fullscreen mode

The : and / characters are structural — encoding them destroys the URL.

Beware double encoding

Encoding an already-encoded string produces garbage: %20 becomes %2520. This usually happens when a value passes through two layers (e.g., your code encodes it and the HTTP library encodes it again). The fix is to encode exactly once, at the boundary where you assemble the URL.

The modern alternative: URLSearchParams

For query strings, the URLSearchParams API handles encoding for you and is usually the cleanest choice:

const params = new URLSearchParams({ q: "hello world", tag: "a&b" });
console.log(params.toString());
// "q=hello+world&tag=a%26b"
Enter fullscreen mode Exit fullscreen mode

One quirk to know: URLSearchParams encodes spaces as + (the application/x-www-form-urlencoded convention), while encodeURIComponent produces %20. Both are valid in query strings, and servers decode either form. decodeURIComponent does not turn + back into a space, though — so pair it with encodeURIComponent output, not with form-encoded strings.

When you'd rather not write code

If you just need to encode or decode a string quickly, the free URL encoder/decoder on Toolstack does it instantly in your browser — no signup, everything runs client-side so your data never leaves your device. Useful for one-off fixes like an API key with special characters in a query string.

Takeaways

  • encodeURIComponent is for individual values; encodeURI is for whole URLs.
  • Never encode a full URL with encodeURIComponent — it will escape the : and / that hold the URL together.
  • Encode exactly once to avoid double encoding (%2520).
  • For query strings, consider URLSearchParams, which encodes for you.
  • For quick one-offs, a free online URL encoder/decoder gets it done without any setup.

Top comments (0)