A URL is not free text. The characters it may contain are defined by RFC 3986, and everything outside that safe set — spaces, accents, symbols, even some punctuation — must be rewritten before the URL leaves your browser. That rewriting is called percent-encoding, and it is why spaces turn into %20 and slashes sometimes become %2F.
What percent-encoding actually does
Percent-encoding replaces a character with a percent sign followed by the two-digit hexadecimal value of its bytes in UTF-8. A space is byte 0x20, so it becomes %20. The letter "é" is two UTF-8 bytes (0xC3 0xA9), so it becomes %C3%A9. Decoding simply reverses the process: find every %XX and turn it back into the original byte.
Common encoded characters
| Character | Encoded | Why it matters |
|---|---|---|
| space | %20 | Spaces are illegal in URLs and terminate them early. |
| / | %2F | Separates path segments. Encoding it hides a slash inside a value. |
| ? | %3F | Starts the query string; encoding it keeps it as literal data. |
| # | %23 | Starts a fragment. An unescaped # inside a value is lost. |
| & | %26 | Separates query parameters, so it must be escaped inside a value. |
| = | %3D | Separates a key from its value. |
| % | %25 | The escape character itself — encode it or decoding breaks. |
| + | %2B | Means "plus" in a URL; + in a query often means a space. |
Reserved vs unreserved characters
Reserved characters (:/?#[]@!$&'()*+,;=) have special meaning in one part of the URL and may behave differently in another. Unreserved characters (A–Z a–z 0–9 - _ . ~) never need encoding. The rule of thumb: encode anything that is not unreserved unless you specifically want its reserved meaning.
encodeURI vs encodeURIComponent
JavaScript ships two functions, and confusing them is the most common URL bug:
encodeURI()encodes a complete URL. It leaves reserved characters such as/ ? & = #intact because they are structural, soencodeURI("https://a.com/b?q=1 2")keeps the path and query readable.encodeURIComponent()encodes a single value. It escapes/ ? & = #too, so the value cannot break out of the slot it is pasted into. This is what you use for query-parameter values.
A query-string example
You want to search for the term a&b=c. If you build the URL with encodeURI, the & and = survive and invent two fake parameters — ?q=a&b=c becomes a query with q=a and b=c. With encodeURIComponent the term becomes a%26b%3Dc, so the server receives exactly one value: ?q=a%26b%3Dc.
To encode or decode a URL or a single query value without touching your code, use our URL encoder / decoder. If your next step is turning structured data into a file, see the guide on JSON vs CSV.