Developer Tools

URL encoding explained: why a space becomes %20, which characters need it, and the encodeURI vs encodeURIComponent trap

What does %20 mean in a link? Which characters are safe in a URL and which are not, how Hindi and accented letters are encoded, why an ampersand can silently split your parameter, and what double encoding (%2520) looks like. With a reference table and real examples.

By the Toolcloak team22 October 20264 min read
In this article
  1. How percent encoding works
  2. The four kinds of character
  3. Reference table
  4. The ampersand that split a parameter
  5. encodeURI against encodeURIComponent
  6. Double encoding
  7. Plus or %20?
  8. A practical checklist

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.

Same idea, different lengths
%20A space1 byte
%C3%A9The letter é2 bytes
18 codesThe Hindi word नमस्ते6 characters × 3 bytes
54 charsIts encoded length%E0%A4%A8%E0%A4%AE…

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.

Paste text or a link and encode it, or paste a %-encoded string and decode it back to readable text.Open URL Encoder

The four kinds of character

What needs encoding and what does not
Unreserved: safeA–Z, a–z, 0–9 and the four marks - _ . ~. Never need encoding.
Reserved: have a job: / ? # [ ] @ ! $ & ' ( ) * + , ; = mark parts of the URL. Encode them when they are part of your data.
Unsafe: always encodeSpace, quotes, < > { } | \ ^ % and control characters.
Non-English: encode as UTF-8Hindi, Tamil, Arabic, accented letters, emoji and symbols.

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

CharacterEncodedWhy it matters
space%20Breaks the link if left as it is
&%26Otherwise starts a new parameter
=%3DOtherwise splits key from value
?%3FOtherwise starts the query string
#%23Otherwise starts the fragment, and the rest is lost
+%2BOtherwise may be read as a space
/%2FOtherwise adds a path level
,%2CSafe in most places, encoded in values
%%25The escape character itself
@%40Otherwise 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.

Searching for “rock & roll”
Not encodedBroken
  • ?q=rock & roll
  • Reads as q=“rock ” and a second key “ roll”
  • The search gets only half the words
EncodedWorks
  • ?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.

InputencodeURIencodeURIComponent
a b&c=da%20b&c=da%20b%26c%3Dd
cafécaf%C3%A9caf%C3%A9
100% नकद100%25%20%E0%A4%A8%E0%A4%95%E0%A4%A6100%25%20%E0%A4%A8%E0%A4%95%E0%A4%A6
https://x.com/a b?q=1https://x.com/a%20b?q=1https%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.

“a b” encoded twice
  1. 1Originala b
  2. 2Encode oncea%20b. This is correct.
  3. 3Encode againa%2520b. The % became %25.
  4. 4Server decodes oncea%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

  1. Encode each value separately, then join with ?, & and =.
  2. Encode non-English text as UTF-8. Any modern tool does this.
  3. Keep slashes in the path, and encode them only when they are part of a name.
  4. Decode once when you read a value back. Do not decode twice.
  5. 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.