In this article
A web address can only safely carry a small set of plain characters. Everything else, from a space to a Hindi letter to an ampersand, has to be written as a percent sign followed by two hexadecimal digits. That is URL encoding, and it is why you see %20 in links. Getting it wrong gives broken links, missing parameters and pages that open fine on your laptop and fail for everyone else.
How percent encoding works
Each character is turned into its bytes in UTF-8, and each byte is written as % plus two hex digits. A space is the single byte 32, which is hex 20, so it becomes %20. The letter é takes two bytes (C3 and A9), so it becomes %C3%A9.
Each Devanagari letter is three bytes in UTF-8, so a six-character word becomes eighteen percent codes. Browsers show the readable word but send the encoded form.
The four kinds of character
- _ . ~. Never need encoding.: / ? # [ ] @ ! $ & ' ( ) * + , ; = mark parts of the URL. Encode them when they are part of your data.< > { } | \ ^ % and control characters.A reserved character is fine when it does its normal job. The ? that starts the query is fine. A ? inside a search term is not.
Reference table
| Character | Encoded | Why it matters |
|---|---|---|
| space | %20 | Breaks the link if left as it is |
| & | %26 | Otherwise starts a new parameter |
| = | %3D | Otherwise splits key from value |
| ? | %3F | Otherwise starts the query string |
| # | %23 | Otherwise starts the fragment, and the rest is lost |
| + | %2B | Otherwise may be read as a space |
| / | %2F | Otherwise adds a path level |
| , | %2C | Safe in most places, encoded in values |
| % | %25 | The escape character itself |
| @ | %40 | Otherwise read as a user marker |
A good habit is to encode every value that came from a person or a database. Never assume it contains only letters and numbers.
The ampersand that split a parameter
Suppose you build a search link for “rock & roll”. Dropped in unencoded, the ampersand ends the parameter, and roll becomes a stray key with no value.
?q=rock & roll- Reads as q=“rock ” and a second key “ roll”
- The search gets only half the words
?q=rock%20%26%20roll- One parameter: q=“rock & roll”
- The server gets the whole phrase
The same problem appears with =, # and +. It also affects WhatsApp links and campaign tags. See the WhatsApp link guide and UTM naming rules.
encodeURI against encodeURIComponent
JavaScript has two functions and they do different jobs. `encodeURI` is for a whole URL, so it leaves characters such as :, /, ?, & and = alone. `encodeURIComponent` is for a single value, so it encodes all of those. Using the first on a value is a very common bug.
| Input | encodeURI | encodeURIComponent |
|---|---|---|
| a b&c=d | a%20b&c=d | a%20b%26c%3Dd |
| café | caf%C3%A9 | caf%C3%A9 |
| 100% नकद | 100%25%20%E0%A4%A8%E0%A4%95%E0%A4%A6 | 100%25%20%E0%A4%A8%E0%A4%95%E0%A4%A6 |
| https://x.com/a b?q=1 | https://x.com/a%20b?q=1 | https%3A%2F%2Fx.com%2Fa%20b%3Fq%3D1 |
Rule of thumb: build the URL from parts, and run encodeURIComponent on each value. Use encodeURI only on a complete address you want to keep intact.
Double encoding
If you encode a string that is already encoded, the % itself becomes %25, and %20 turns into %2520. The server decodes once and sees the text %20 instead of a space. It is a sign that two layers each tried to be helpful.
- 1Original
a b - 2Encode once
a%20b. This is correct. - 3Encode again
a%2520b. The % became %25. - 4Server decodes once
a%20b. The user sees a stray %20 on the page.
If a link shows %20 in the page text, look for the step that encoded it a second time, then remove one.
Plus or %20?
Inside a query string, many systems treat + as a space. That is the older form encoding style, and it is what HTML forms and the URLSearchParams object produce. In the path of a URL, + means a literal plus sign, and a space must be %20. When in doubt use %20, which works in both places.
A practical checklist
- Encode each value separately, then join with
?,&and=. - Encode non-English text as UTF-8. Any modern tool does this.
- Keep slashes in the path, and encode them only when they are part of a name.
- Decode once when you read a value back. Do not decode twice.
- Test the finished link in a private window and by reading the address bar.
Going the other way? The URL Decoder turns %20-style text back into words.
Questions people ask
What does %20 mean in a URL?
%20 is a space. URLs cannot contain a raw space, so it is written as a percent sign and the hexadecimal code for the space character, which is 20.
How do I encode a URL?
Use a URL encoder, or in JavaScript call encodeURIComponent on each value before adding it to the link. It turns spaces, ampersands and non-English letters into percent codes.
What is the difference between encodeURI and encodeURIComponent?
encodeURI is for a full URL and leaves characters like : / ? & = alone. encodeURIComponent is for a single value and encodes those too. Use it for query values.
How are Hindi letters encoded in a URL?
Each letter is converted to its UTF-8 bytes and each byte is written as %XX. A Devanagari letter is three bytes, so one letter becomes three percent codes.
Why is there a %25 in my URL?
%25 is an encoded percent sign. If you see %2520 where you expected %20, the text was encoded twice.
Is + the same as %20?
In a query string, often yes, because forms use + for a space. In the path part of a URL, + is a literal plus sign. %20 is the safe choice everywhere.
Which characters are safe in a URL?
Letters A to Z and a to z, digits 0 to 9, and the marks - _ . ~ are always safe. Everything else may need to be encoded depending on where it appears.

