What Is URL Encoding (Percent-Encoding)?
URL encoding, formally known as percent-encoding, is a mechanism defined in RFC 3986 for representing characters in a Uniform Resource Identifier (URI) that are not allowed or have special meaning. When you type a URL into your browser's address bar, behind the scenes certain characters are converted into a percent sign followed by two hexadecimal digits representing the character's byte value in UTF-8. For example, a space character becomes %20, an ampersand becomes %26, and a question mark becomes %3F.
This encoding is essential because URLs can only be sent over the Internet using the ASCII character set. Characters outside ASCII, such as Chinese characters, emoji, or accented letters, must be encoded before being placed in a URL. Even certain ASCII characters like spaces, curly braces, and pipe symbols are "unsafe" in URLs and require encoding.
Why Do We Need URL Encoding?
URLs serve as the universal addressing system of the web. They are parsed by browsers, servers, proxies, and countless other systems. Without a consistent encoding scheme, ambiguity would arise. Consider a search query like price=10¤cy=USD. If you include the literal & character inside a query parameter value, the server would incorrectly interpret it as a parameter separator. URL encoding eliminates this ambiguity by converting the & to %26 when it appears inside a value.
Common scenarios where URL encoding is necessary include: building query strings with user-provided input, constructing API requests with dynamic parameters, embedding URLs inside other URLs (such as redirect URIs in OAuth flows), and handling internationalized domain names and paths.
encodeURI vs encodeURIComponent: When to Use Which
JavaScript provides two built-in functions for URL encoding, and choosing the right one is critical to avoid broken URLs or security issues.
encodeURIComponent
encodeURIComponent() encodes all special characters, including : / ? # [ ] @ ! $ & ' ( ) * + , ; =. It is designed for encoding a single component of a URI, such as a query parameter key or value, a path segment, or a fragment identifier.
Use encodeURIComponent when you are building a query string manually:
const query = "hello world & goodbye";
const url = "https://example.com/search?q=" + encodeURIComponent(query);
// Result: https://example.com/search?q=hello%20world%20%26%20goodbyeencodeURI
encodeURI() encodes special characters but preserves characters that have structural meaning in a URL: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. It is designed for encoding a complete URI where you want to keep the URL structure intact but encode any unsafe characters in the path or query values.
const url = "https://example.com/path/hello world?name=John Doe";
const encoded = encodeURI(url);
// Result: https://example.com/path/hello%20world?name=John%20DoeNotice how encodeURI preserves the ://, /, ?, and = characters. If you had used encodeURIComponent on the entire URL, it would break by encoding the slashes and colon.
Quick Decision Rule
- Encoding a query parameter value? Use
encodeURIComponent. - Encoding a full URL that may contain spaces or unicode? Use
encodeURI. - Encoding a path segment? Use
encodeURIComponent. - Unsure? Default to
encodeURIComponentfor individual pieces, and assemble the URL yourself.
Common Special Characters and Their Encoded Forms
Below is a reference table of frequently encountered characters and their percent-encoded equivalents:
| Character | Name | Encoded |
|---|---|---|
| (space) | Space | %20 |
| ! | Exclamation mark | %21 |
| # | Hash / Fragment | %23 |
| $ | Dollar sign | %24 |
| & | Ampersand | %26 |
| + | Plus sign | %2B |
| / | Forward slash | %2F |
| : | Colon | %3A |
| = | Equals sign | %3D |
| ? | Question mark | %3F |
| @ | At sign | %40 |
Related Tools
How URL Encoding Works Under the Hood
Percent-encoding operates on the raw bytes of a character's UTF-8 representation. For ASCII characters (code points 0–127), this is a single byte. For example, the space character (U+0020) has the byte value 0x20, so it becomes %20.
For multi-byte characters, each byte is encoded separately. The Chinese character 你 (U+4F60) is encoded in UTF-8 as three bytes: 0xE4 0xBD 0xA0, which becomes %E4%BD%A0. Emoji and other characters in higher Unicode planes require four bytes. The rocket emoji (U+1F680) becomes %F0%9F%9A%80.
Unreserved characters, defined as letters (A–Z, a–z), digits (0–9), hyphen (-), underscore (_), period (.), and tilde (~), are never encoded. All other characters may be encoded depending on their position in the URI.
Common Pitfalls
- Double encoding: If you encode a string that is already encoded,
%20becomes%2520(the%itself gets encoded). Always check whether your input is already encoded before encoding again. - Using encodeURI on parameter values: Since
encodeURIdoes not encode&or=, using it to encode a query value containing those characters will break the query string. - Plus sign vs %20: In
application/x-www-form-urlencodedformat (used by HTML forms), spaces are represented as+instead of%20. JavaScript'sencodeURIComponentuses%20. Be aware of this difference when working with form data. - Forgetting to decode on the server: Most web frameworks automatically decode URL parameters, but if you are parsing raw URLs or building custom routing logic, remember to call the appropriate decode function.
Frequently Asked Questions
What is the difference between URL encoding and HTML encoding?
URL encoding (percent-encoding) converts characters into %XX format for use in URLs. HTML encoding converts characters into HTML entities like &, <, and ' for safe display in HTML documents. They serve different purposes and are not interchangeable.
Is URL encoding the same as Base64 encoding?
No. URL encoding converts individual characters to their percent-encoded byte representations while keeping most of the original text readable. Base64 encoding converts the entire input into a different alphabet (A–Z, a–z, 0–9, +, /), producing output that bears no visual resemblance to the input. Base64 is often used to embed binary data in text formats, while URL encoding is specifically for making strings safe for use in URLs.
Do I need to URL-encode every character in a URL?
No. Unreserved characters (letters, digits, -, _, ., ~) never need encoding. Reserved characters (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) only need encoding when they appear in a context where they are not being used as delimiters. For example, a / in a path is a delimiter and should not be encoded, but a / inside a query parameter value should be encoded.
Why does my browser show decoded URLs in the address bar?
Modern browsers display the decoded, human-readable version of URLs for better usability. Internally, the browser sends the properly encoded URL to the server. If you copy the URL from the address bar, some browsers will re-encode it while others may give you the decoded version. You can verify the actual encoded URL by inspecting the network request in the browser's developer tools.
Is this tool safe to use with sensitive data?
Yes. All encoding and decoding happens entirely in your browser using JavaScript's built-in encodeURIComponent, encodeURI, decodeURIComponent, and decodeURI functions. No data is sent to any server.