Every %20 you've ever seen in a URL is doing real work — turning characters a URL can't safely carry into a form it can. Here's how percent-encoding actually works, why encodeURIComponent and encodeURI aren't interchangeable, and what happens when Hindi or Arabic text ends up in a link.
A URL can only reliably transmit a limited set of ASCII characters. Anything outside that safe set — spaces, symbols like & and ? when used outside their structural role, or non-Latin scripts entirely — needs to be converted into a form the URL spec permits. Percent-encoding does this by replacing each problematic character with a % followed by two hexadecimal digits representing that character's byte value.
🔤
ASCII-Safe Output
Encoded URLs only ever contain characters the URL spec universally allows.
🔢
Hex Byte Values
Each %XX represents one byte, shown in hexadecimal.
🔄
Fully Reversible
Decoding exactly reconstructs the original text — no information is lost.
🌐
Universal Standard
Every browser, server, and language implements the same core rules.
Reserved vs Unreserved Characters
The URL specification splits characters into two categories that behave very differently under encoding.
Category
Examples
Encoding Behaviour
Unreserved
A-Z, a-z, 0-9, - _ . ~
Never need encoding — always safe as-is
Reserved
: / ? # [ ] @ ! $ & ' ( ) * + , ; =
Have structural meaning; encoded only when used as literal data, not as structure
💡
This is exactly why context matters so much: a / in the path portion of a URL is structural and must stay unencoded, but a literal / character inside a search query value needs to be encoded as %2F so it isn't mistaken for a path separator.
encodeURIComponent vs encodeURI
JavaScript provides two built-in encoding functions, and mixing them up is one of the most common sources of broken links in web development.
Function
Encodes
Preserves
Use For
encodeURIComponent
Nearly everything, including & = ? /
Only unreserved characters
A single value — search term, parameter
encodeURI
Spaces and unsafe characters
Structural characters : / ? & =
A complete, already-structured URL
🚨
The common mistake: using encodeURI on a single parameter value leaves characters like & and = unencoded, which can corrupt the query string if that value itself contains them. Using encodeURIComponent on a full URL, meanwhile, mangles the :// and other structural characters, breaking the link entirely.
Why Spaces Become %20 or +
%20 is the standard, universally correct percent-encoding for a space, valid anywhere in a URL. The + symbol is a narrower, older convention specific to query strings formatted as application/x-www-form-urlencoded — a legacy of how HTML forms have traditionally submitted data.
When in doubt, %20 is the safer, more universally correct choice outside that one specific legacy context.
Encoding Non-English Text via UTF-8
Non-ASCII characters — Hindi, Arabic, Chinese, emoji — can't be represented by a single byte the way basic Latin characters can. They're first converted to their UTF-8 byte representation, which for most Devanagari or Arabic characters takes 2-3 bytes, and then each individual byte is percent-encoded separately.
💡
This is why a single Hindi word in a URL can expand into a surprisingly long string of %XX sequences — each visible character might correspond to two or three separate encoded bytes, not one. The encoded length of non-Latin text is not a reliable indicator of how many characters it represents.
Worked Example
Encoding the search query café & chai for use as a URL parameter value:
Character
Encoded As
Why
c, a, f
c, a, f
Unreserved ASCII — no encoding needed
é
%C3%A9
Non-ASCII — 2 UTF-8 bytes, each percent-encoded
(space)
%20
Standard space encoding
&
%26
Reserved character, encoded since it's literal data here, not structure
✅
Final result: caf%C3%A9%20%26%20chai — safe to insert as a single query parameter value without breaking the surrounding URL structure. Try ToolLoom's URL Encoder / Decoder to see this transformation live, in both component and full-URI modes.
Where URL Encoding Matters in Practice
Search query parameters — user-typed search terms need encoding before appending to a URL
Sharing links with special characters — file names or titles containing spaces, symbols, or non-Latin text
API request URLs — dynamic path segments or query values built from variable data
Redirect and callback URLs — a full URL passed as a parameter value to another URL needs component-level encoding
Debugging "broken" links — unexpected characters in a URL are a common cause of 404s or malformed requests
Common Encoding Mistakes
Using encodeURI on a single parameter value — leaves & and = unencoded, risking query string corruption
Using encodeURIComponent on a whole URL — mangles the :// and other structural characters
Double-encoding — encoding an already-encoded string turns %20 into %2520, a frequent copy-paste error
Assuming + always means space — only true within form-urlencoded query strings, not universally
Forgetting non-Latin text needs UTF-8 byte-level encoding — not a simple one-character-to-one-code mapping
💻 Encode or Decode Instantly — Free
Component and full-URI modes, live preview, full Unicode support — runs entirely in your browser.
URL encoding, also called percent-encoding, converts characters that aren't safe or have special meaning in a URL into a percent sign followed by two hexadecimal digits representing the character's byte value. It's necessary because URLs can only reliably contain a limited set of ASCII characters — anything else, including spaces, symbols, and non-Latin text, needs to be encoded to travel safely through browsers, servers, and network infrastructure without being misinterpreted or corrupted.
encodeURIComponent encodes nearly every special character, including &, =, ?, and /, making it the correct choice for encoding a single value — like a search term or parameter — that will be inserted into a URL. encodeURI preserves the characters that give a complete URL its structure (such as :, /, ?, &, =) and only encodes things like spaces, making it appropriate for encoding an entire, already-structured URL rather than an individual piece of it. Using the wrong one is a common source of broken links.
%20 is the standard, universally correct percent-encoding for a space character anywhere in a URL. The + symbol is an older, narrower convention specific to URL query strings formatted as application/x-www-form-urlencoded, inherited from how HTML forms have traditionally submitted data. Outside that specific query-string context, + is not a valid space encoding and should not be used.
Non-ASCII characters are first converted to their UTF-8 byte representation — most Devanagari or Arabic characters take 2-3 bytes in UTF-8 — and then each individual byte is percent-encoded separately. This means a single Hindi character in a URL often becomes a sequence of several %XX groups rather than one, which is why encoded non-Latin URLs look considerably longer than the visible text would suggest.
Decoding fails or produces garbled output when the percent-encoded sequence doesn't correspond to valid UTF-8 bytes — for example, an incomplete %XX sequence, a stray percent sign not followed by two valid hexadecimal digits, or text that was encoded using a different character encoding altogether. This almost always traces back to the input not having been properly encoded in the first place, or being truncated somewhere along the way.
Generally, only specific dynamic parts need encoding — query parameter values, search terms, or user-generated text being inserted into a URL — not the whole URL string. Encoding an entire well-formed URL with a component-level function like encodeURIComponent would incorrectly escape the structural characters (like :// and the domain's dots), breaking the URL rather than protecting it.
About ToolLoom: We build free tools for Indian students, professionals and creators. All encoding and decoding happens instantly in your browser using native JavaScript functions — nothing is uploaded or stored. Found an error? Email contact@toolloom.in