What is URL Encoding? A Complete Guide to Percent-Encoding
Every time you search, click a link with special characters, or submit a web form, URL encoding is working behind the scenes. It converts unsafe characters into a format that can travel safely across the internet.
Table of Contents
- What is a URL?
- Anatomy of a URL
- What is URL Encoding?
- Why Do We Need URL Encoding?
- How URL Encoding Works
- Reserved vs Unreserved Characters
- Common URL-Encoded Characters
- Encoding Unicode and International Characters
- URL Encoding in Programming Languages
- encodeURI vs encodeURIComponent
- Common Mistakes with URL Encoding
- Real-World Examples
What is a URL?
A URL, or Uniform Resource Locator, is the address of a resource on the internet. Pages, images, API endpoints, files, and downloads all have URLs.
A URL tells the browser where the resource is, what protocol to use, and which extra data, such as query parameters or fragments, should be applied.
For example, https://www.example.com/search?q=hello+world contains a scheme, host, path, and query string.
Anatomy of a URL
A full URL can contain several components:
https://user:pass@www.example.com:443/path/page?key=value&q=test#section
scheme userinfo host port path query fragment| Component | Example | Description |
|---|---|---|
| Scheme | https | Protocol used to access the resource |
| User info | user:pass | Optional credentials, rarely used today |
| Host | www.example.com | Domain name or IP address of the server |
| Port | 443 | Server port, usually implicit for HTTP or HTTPS |
| Path | /path/page | Specific resource location on the server |
| Query | key=value&q=test | Key-value data after the question mark |
| Fragment | #section | A page bookmark that is not sent to the server |
What is URL Encoding?
URL encoding, also called percent-encoding, converts characters that are unsafe or not allowed in URLs into a safe representation.
The format is a percent sign followed by two hexadecimal digits. A space becomes %20 because its ASCII byte is decimal 32, or hex 20.
Percent-encoding is defined by URI standards such as RFC 3986 and is a core part of how URLs safely carry text.
Before encoding:
https://example.com/search?q=hello world&lang=en
After encoding:
https://example.com/search?q=hello%20world&lang=en
Space becomes %20Why Do We Need URL Encoding?
URL encoding is necessary for several reasons:
- Reserved characters have meaning - characters like
?,&,=, and#delimit URL parts. - Spaces are not allowed directly - URLs need spaces encoded as
%20or sometimes+in form data. - Non-ASCII text needs bytes - Thai, Japanese, accented letters, and emoji must be converted to UTF-8 bytes first.
- Data integrity matters - encoding prevents browsers, proxies, and servers from misreading user data as URL structure.
- Security depends on context - correct encoding helps prevent parameter injection and broken redirects.
How URL Encoding Works
The process is simple:
- Take the character that needs encoding.
- Convert it to UTF-8 bytes.
- Write each byte as % followed by two uppercase hexadecimal digits.
For ASCII characters, each character is one byte:
Character: space ASCII: 32 Hex: 20 Encoded: %20
Character: ! ASCII: 33 Hex: 21 Encoded: %21
Character: # ASCII: 35 Hex: 23 Encoded: %23
Character: @ ASCII: 64 Hex: 40 Encoded: %40For non-ASCII characters, UTF-8 can produce multiple bytes:
Character: é UTF-8 bytes: C3 A9 Encoded: %C3%A9
Character: ñ UTF-8 bytes: C3 B1 Encoded: %C3%B1
Character: 日 UTF-8 bytes: E6 97 A5 Encoded: %E6%97%A5
Character: 😀 UTF-8 bytes: F0 9F 98 80 Encoded: %F0%9F%98%80Reserved vs Unreserved Characters
RFC 3986 groups URL characters into reserved and unreserved categories.
Unreserved characters
Letters, digits, hyphen, underscore, period, and tilde are safe and usually do not need encoding: A-Z a-z 0-9 - _ . ~
Reserved characters
Characters such as : / ? # [ ] @ ! $ & ' ( ) * + , ; = may have structural meaning. Encode them when they are data, not syntax.
Unsafe or special characters
Spaces, percent signs, quotes, angle brackets, non-ASCII characters, and control characters should be encoded.
Common URL-Encoded Characters
| Character | Encoded | Character | Encoded |
|---|---|---|---|
space | %20 | ! | %21 |
" | %22 | # | %23 |
$ | %24 | % | %25 |
& | %26 | ' | %27 |
( | %28 | ) | %29 |
+ | %2B | , | %2C |
/ | %2F | : | %3A |
? | %3F | = | %3D |
Encoding Unicode and International Characters
Modern URLs often contain international text. The character is first encoded as UTF-8, then each byte is percent-encoded.
Example: Encoding "café" in a URL
c -> c (ASCII, no encoding needed)
a -> a (ASCII, no encoding needed)
f -> f (ASCII, no encoding needed)
é -> UTF-8 C3 A9 -> %C3%A9
Result: caf%C3%A9
Full URL: https://example.com/search?q=caf%C3%A9Browsers often show readable characters in the address bar while sending the encoded form in the actual request.
URL Encoding in Programming Languages
Most languages include helpers for URL encoding and decoding:
JavaScript
// Encode a single query parameter value
encodeURIComponent("hello world & goodbye")
// "hello%20world%20%26%20goodbye"
// Decode it back
decodeURIComponent("hello%20world%20%26%20goodbye")
// "hello world & goodbye"
// Encode an entire URI while keeping URL structure intact
encodeURI("https://example.com/path?q=hello world")
// "https://example.com/path?q=hello%20world"
// URLSearchParams handles query encoding automatically
const params = new URLSearchParams({ q: "hello world", lang: "en" });
params.toString();
// "q=hello+world&lang=en"Python
from urllib.parse import quote, unquote, urlencode
quote("hello world & goodbye")
# 'hello%20world%20%26%20goodbye'
unquote("hello%20world%20%26%20goodbye")
# 'hello world & goodbye'
urlencode({"q": "hello world", "lang": "en"})
# 'q=hello+world&lang=en'
quote("/path/to/resource", safe="/")
# '/path/to/resource'PHP
// Spaces become %20
rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"
// Spaces become + for form-style data
urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"
rawurldecode("hello%20world"); // "hello world"
urldecode("hello+world"); // "hello world"Java
import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;
URLEncoder.encode("hello world", StandardCharsets.UTF_8);
// "hello+world"
URLDecoder.decode("hello%20world", StandardCharsets.UTF_8);
// "hello world"encodeURI vs encodeURIComponent
JavaScript has two similar-looking functions, but they are used for different jobs:
| Function | Use Case | Does Not Encode |
|---|---|---|
encodeURI() | Encoding a complete URL while preserving URL structure | : / ? # [ ] @ ! $ & ' ( ) * + , ; = |
encodeURIComponent() | Encoding a single parameter value or path segment | - _ . ~ ! ' ( ) * |
const value = "price=10¤cy=USD";
// Wrong for parameter values: & and = are not encoded
encodeURI("https://api.com/search?filter=" + value);
// "https://api.com/search?filter=price=10¤cy=USD"
// Server sees two parameters: filter=price=10 and currency=USD
// Correct: encode the value as one component
"https://api.com/search?filter=" + encodeURIComponent(value);
// "https://api.com/search?filter=price%3D10%26currency%3DUSD"
// Server sees one parameter: filter=price=10¤cy=USDRule of thumb
Use encodeURIComponent() for individual values such as query parameters and path segments. Use encodeURI() only for an already assembled full URL.
Common Mistakes with URL Encoding
1. Double encoding
Encoding text that is already encoded turns %20 into %2520 because the percent sign itself becomes %25. Encode once at the boundary where data enters the URL.
2. Using encodeURI for query values
encodeURI does not encode & or =, so user input can accidentally become extra query parameters. Use encodeURIComponent for values.
3. Confusing + and %20
+ means space in application/x-www-form-urlencoded data, but decodeURIComponent does not convert + to a space automatically.
4. Not encoding file names or path segments
File names can contain spaces and special characters. Encode each path segment before inserting it into a URL.
const encoded = encodeURIComponent("hello world");
// "hello%20world"
encodeURIComponent(encoded);
// "hello%2520world" <-- wrong, % became %25
const value = "hello world";
const url = "/search?q=" + encodeURIComponent(value);
// Encode once at the boundary// Broken or ambiguous URL
const url = "/files/" + "my report (final).pdf";
// "/files/my report (final).pdf"
// Properly encoded path segment
const url = "/files/" + encodeURIComponent("my report (final).pdf");
// "/files/my%20report%20(final).pdf"Real-World Examples
URL encoding appears constantly in normal web work:
Google Search
https://www.google.com/search?q=what+is+URL+encoding%3F
Spaces become +
Question mark becomes %3FAPI Requests
GET /api/users?name=O%27Brien&city=San%20Francisco
Decoded:
name = O'Brien
city = San FranciscoEmail Mailto Links
mailto:user@example.com?subject=Hello%20World&body=Hi%2C%20how%20are%20you%3F
Decoded:
subject = Hello World
body = Hi, how are you?Redirect URLs
https://auth.example.com/login?redirect=https%3A%2F%2Fapp.example.com%2Fdashboard%3Ftab%3Dsettings
Decoded redirect value:
https://app.example.com/dashboard?tab=settingsEncode & Decode URLs Instantly
Use our free URL Encoder & Decoder tool to encode or decode any URL, query parameter, or text right in your browser.
Try URL Encoder & DecoderReferences
- Berners-Lee, T., Fielding, R., & Masinter, L. (2005). RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. https://datatracker.ietf.org/doc/html/rfc3986
- Berners-Lee, T., Masinter, L., & McCahill, M. (1994). RFC 1738 - Uniform Resource Locators (URL). https://datatracker.ietf.org/doc/html/rfc1738
- Mozilla Developer Network. encodeURIComponent() - JavaScript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
- WHATWG. URL Standard. https://url.spec.whatwg.org/
- Python Software Foundation. urllib.parse - Parse URLs into components. https://docs.python.org/3/library/urllib.parse.html