We have all been there. You are browsing the web, you find a cool article, and you copy the link from your browser’s address bar to send to a friend. But when you paste it into your chat app, the clean, readable link turns into a massive, ugly wall of text. It is suddenly stuffed with percent signs, numbers, and letters. It looks like your cat walked across your keyboard, or like your computer is having a mild panic attack.
What you are looking at is URL encoding, which is also known as percent encoding.
It might look like a mess, but it is actually one of the most important protocols keeping the web running smoothly. Without it, search engines would break, API requests would fail, and sharing links with non-English characters or emojis would be completely impossible.
In this guide, we will look at why URL encoding exists, how it works step by step, and how different programming languages handle it. We will also explore the common bugs that developers run into and show you how to encode and decode URLs safely without leaking your private data.
Why Do We Need URL Encoding?
To understand why we have to encode URLs, we have to look back at the history of the internet.
When Tim Berners-Lee was designing the World Wide Web in the late 1980s and early 1990s, he had to define how web addresses would work. He wrote the specifications that eventually became RFC 3986, which is the official standard for Uniform Resource Identifiers (URIs).
Back then, the internet was tiny, and almost all computer communication was based on US-ASCII. ASCII is a character encoding standard that represents one hundred and twenty-eight characters. It includes English letters, numbers, and a few basic punctuation marks.
Because of this history, the standard for URLs was built strictly around ASCII. If a character is not in the standard ASCII set, it cannot exist in a raw URL.
But it is not just about foreign languages or emojis. Even standard ASCII characters can cause major issues.
A URL uses specific characters to define its structure. For example, the colon and double slash separate the protocol from the domain name. The single slash separates folders in a path. The question mark starts the query parameters, and the ampersand separates individual parameters.
What happens if you want to search for the phrase “cats & dogs” on a website?
If you write the URL as https://example.com/search?q=cats & dogs, the browser will get confused. It sees the ampersand and thinks you are starting a new query parameter named dogs. The server will receive a query for q=cats and a second parameter called dogs which has no value. Your search will fail.
To prevent this confusion, we must encode any characters that have structural meaning, as well as any characters that fall outside the basic ASCII range.
Reserved vs Unreserved Characters
RFC 3986 divides the characters we can use in a URL into two distinct groups.
Unreserved Characters
These are characters that have no special structural meaning in a URL. You can use them anywhere, at any time, without encoding them.
The unreserved characters are:
- Upper-case letters:
AthroughZ - Lower-case letters:
athroughz - Numbers:
0through9 - Four specific symbols: hyphen (
-), period (.), underscore (_), and tilde (~)
Reserved Characters
These are characters that have a special purpose in defining the structure of a URL. If you want to use them as actual data (for example, putting a question mark inside a search query), you must encode them.
The reserved characters include:
- Component separators: colon (
:), slash (/), question mark (?), hash (#), square brackets ([and]), and the at sign (@) - Sub-component separators: exclamation mark (
!), dollar sign ($), ampersand (&), single quotes ('), parentheses ((and)), asterisk (*), plus sign (+), comma (,), semicolon (;), and the equals sign (=)
If a character is not on either of these lists, it is considered unsafe and must always be encoded. This includes spaces, control characters, and all non-ASCII characters.
How Percent Encoding Works Under the Hood
The basic rule of percent encoding is simple: replace the unsafe character with a percent sign (%) followed by the two-digit hexadecimal representation of its byte value.
Let us look at a few examples to see how this works.
Example 1: The Space Character
The space character is the most common character you will need to encode.
- In the ASCII table, a space has a decimal value of 32.
- If you convert the decimal number 32 into hexadecimal, you get 20.
- Therefore, a space is encoded as
%20.
Example 2: The Ampersand
Let us look at the ampersand (&), which is a reserved character because it separates query parameters.
- The ASCII decimal value of
&is 38. - In hexadecimal, 38 becomes 26.
- Therefore, an ampersand is encoded as
%26.
Example 3: Emojis and Multi-Byte UTF-8 Characters
What happens when we want to encode a modern character like the Rocket Emoji (🚀)?
ASCII only goes up to decimal 127, so it has no idea what an emoji is. Modern systems use UTF-8, which represents characters using one to four bytes. The Rocket Emoji is represented in UTF-8 by four bytes:
- First byte:
F0(hexadecimal) - Second byte:
9F(hexadecimal) - Third byte:
9A(hexadecimal) - Fourth byte:
80(hexadecimal)
To percent-encode this emoji, we simply put a percent sign in front of each byte. The result is %F0%9F%9A%80. When a web browser or server sees this sequence, it knows to combine these four bytes back into the Rocket Emoji.
URL Encoding in JavaScript
If you are writing JavaScript, you have two main functions for encoding URLs: encodeURI() and encodeURIComponent().
Many developers use these functions interchangeably, which is a massive mistake. Using the wrong one will break your application.
encodeURI()
This function is designed to encode a complete, fully formed URL. Because it assumes you are giving it a valid URL, it does not encode characters that are necessary for the URL’s structure.
It leaves these characters untouched: :, /, ;, ?, &, =, @, +, $, #, and ,.
const url = "https://example.com/search?q=cats & dogs";
console.log(encodeURI(url));
// Output: "https://example.com/search?q=cats%20&%20dogs"
Notice that the space was encoded to %20, but the ampersand (&) and the question mark (?) were left alone. This is correct if you want to keep the URL structure, but it is incorrect if you wanted the ampersand to be treated as part of the search query.
encodeURIComponent()
This function is designed to encode a single component of a URL, such as the value of a query parameter. It assumes that the string you are passing is pure data, not structural parts of the URL.
Therefore, it encodes almost everything, including reserved characters like :, /, ?, &, and =.
const query = "cats & dogs";
const baseUrl = "https://example.com/search?q=";
console.log(baseUrl + encodeURIComponent(query));
// Output: "https://example.com/search?q=cats%20%26%20dogs"
Notice that both the space (%20) and the ampersand (%26) are encoded. This is the correct way to pass parameters to a server.
Decoding URLs in JavaScript
To reverse the process, JavaScript provides decodeURI() and decodeURIComponent().
Be careful when decoding user input. If a user provides a malformed percent-encoded string (for example, a percent sign followed by letters that are not valid hexadecimal numbers, like %G1), the decoding function will throw a URIError.
To prevent your application from crashing, always wrap your decoding logic in a try-catch block:
function safeDecode(encodedString) {
try {
return decodeURIComponent(encodedString);
} catch (error) {
console.error("Failed to decode URI segment:", error.message);
return encodedString; // Return original string if decoding fails
}
}
URL Encoding in Other Programming Languages
Almost every major backend language has built-in tools to handle percent encoding. Here is a quick reference for how to do it in Python, Node.js, PHP, and Go.
Python
Python provides the urllib.parse module to handle URL encoding.
from urllib.parse import quote, quote_plus
# Standard encoding (spaces become %20)
query = "red & blue"
print(quote(query)) # Output: red%20%26%20blue
# Form-style encoding (spaces become +)
print(quote_plus(query)) # Output: red+%26+blue
Node.js
In Node.js, you can use the standard JavaScript functions or the built-in querystring utility.
const querystring = require('querystring');
const query = "red & blue";
console.log(querystring.escape(query)); // Output: red%20%26%20blue
PHP
PHP has two different functions for URL encoding, which can be confusing.
<?php
$query = "red & blue";
// Standard RFC 3986 encoding (spaces become %20)
echo rawurlencode($query); // Output: red%20%26%20blue
// Application/x-www-form-urlencoded encoding (spaces become +)
echo urlencode($query); // Output: red+%26+blue
?>
Go (Golang)
In Go, you use the net/url package.
package main
import (
"fmt"
"net/url"
)
func main() {
query := "red & blue"
encoded := url.QueryEscape(query)
fmt.Println(encoded) // Output: red+%26+blue
}
Quick Reference Table for Common Characters
Here is a quick lookup table for some of the most common characters you will need to encode when building URLs.
| Character | Name | ASCII Hex Code | URL Encoded Value |
|---|---|---|---|
| Space | 20 | %20 or + |
! | Exclamation Mark | 21 | %21 |
# | Hash / Fragment | 23 | %23 |
$ | Dollar Sign | 24 | %24 |
& | Ampersand | 26 | %26 |
+ | Plus Sign | 2B | %2B |
, | Comma | 2C | %2C |
/ | Forward Slash | 2F | %2F |
: | Colon | 3A | %3A |
; | Semicolon | 3B | %3B |
= | Equals Sign | 3D | %3D |
? | Question Mark | 3F | %3F |
@ | At Sign | 40 | %40 |
Common Pitfalls and How to Avoid Them
URL encoding is simple in theory, but it is a frequent source of bugs in production applications. Here are the most common pitfalls to watch out for.
1. The Double Encoding Nightmare
Double encoding happens when you accidentally run an encoding function on a string that has already been encoded.
For example, if you start with the string red & blue:
- First encoding:
red%20%26%20blue - Second encoding:
red%2520%2526%2520blue
What happened? The encoding function saw the percent signs (%) from the first pass and converted them into %25 (the encoded value for a percent sign).
When the server receives this URL, it will only decode it once, resulting in the literal text red%20%26%20blue instead of the original red & blue.
To avoid this, make sure you only encode parameters once, ideally right before you build the final URL string.
2. Space Encoding: %20 vs +
You might have noticed that some systems encode spaces as %20, while others encode them as a plus sign (+).
This is due to a historic split in web standards.
- Standard URL path segments (defined by RFC 3986) use
%20for spaces. - Query strings sent by HTML forms use the
application/x-www-form-urlencodedformat, which defines space as+.
If you use + in a path segment (for example, https://example.com/tags/red+blue), the server might look for a folder literally named red+blue instead of red blue.
As a general rule, use %20 for spaces unless you are formatting form data or query parameters specifically.
3. Case Sensitivity in Hex Codes
According to the official RFC 3986 specification, the hexadecimal digits in percent encoding are case-insensitive. This means %2f and %2F are technically identical.
However, many legacy backend systems and poorly written server routers are configured to look for exact string matches. If they expect %2F and you send %2f, they might fail to match the route.
It is best practice to always use upper-case letters for hexadecimal values in your encoder tools.
Why Privacy Matters in URL Encoder Tools
When developers need to debug an API payload or decode a webhook URL, they often search for a free URL encoder online.
But here is the catch: many of the top results on Google are hosted by sketchy websites that send your data to their backend servers for processing.
If your URL contains sensitive information, such as:
- Private API tokens (
?api_key=12345) - User passwords or reset tokens
- Personal identifiable information like names, email addresses, or phone numbers
Then sending that URL to a third-party server is a massive security risk. Your sensitive keys and user data could end up in their server logs or database, violating privacy regulations like GDPR.
We built our URL Encoder to solve this problem.
Our tool runs entirely in your browser using local JavaScript. When you paste a URL to encode or decode, the conversion happens instantly on your device. No data is ever sent to our servers. It is fast, secure, and completely private.
You can use the tool safely at TextSorter URL Encoder.
Frequently Asked Questions
Is percent encoding case-sensitive?
The percent sign and the hexadecimal characters can be parsed in both uppercase and lowercase. However, RFC 3986 states that producers of URIs should use uppercase letters for all percent-encoded bytes. If you write your own encoder, you should make sure it outputs uppercase letters to prevent issues with strict servers.
Can I use base64 encoding instead of URL encoding?
Base64 encoding is not a substitute for URL encoding. While base64 converts binary data into ASCII characters, it actually includes symbols like +, /, and = which are reserved characters in URLs. If you want to put a base64 string in a query parameter, you must still run it through a URL encoder to ensure those characters do not break the URL structure.
Why does my browser address bar show clean characters but copies them as percent-encoded?
Modern web browsers try to make URLs readable for humans. If a URL contains non-ASCII characters (like Cyrillic script or emojis), the address bar will display them in their natural form. However, when you copy the URL to your clipboard, the browser automatically converts those characters into percent-encoded strings to ensure the link remains valid when you paste it somewhere else.
What is the maximum length of an encoded URL?
The HTTP protocol does not specify a maximum length for URLs. However, web servers and browsers have their own limits for security and performance reasons. Google Chrome and Microsoft IIS typically limit URL length to around two thousand characters. If you have a massive amount of data to send, you should use an HTTP POST request with a request body instead of putting the data in query parameters.
Does URL encoding compress my data?
No. URL encoding actually makes your data larger. Every unsafe character is replaced by three characters (the percent sign and two hex digits). A single space character goes from one byte to three bytes. If you are encoding a large multi-byte string, the resulting URL can quickly grow to double or triple its original size.