You've probably seen URLs that look like this:
https://example.com/search?q=hello%20world&lang=en https://example.com/search?q=%E6%97%A5%E6%9C%AC%E8%AA%9E
Those %20 and %E6%97%A5 sequences aren't gibberish — they're URL-encoded characters. The first is a space; the second is the Japanese word for "Japanese." Once you understand the encoding rule, you can read and write these strings confidently. Here's how it works.
What is URL Encoding?
URL encoding (formally called percent-encoding) is the mechanism for safely including characters in a URL that would otherwise be ambiguous or invalid. URLs can only contain a defined set of ASCII characters. Everything else — spaces, non-ASCII text like Japanese or Arabic, and certain special characters — must be encoded before it can appear in a URL.
Characters that are safe without encoding (called unreserved characters):
- Uppercase and lowercase letters:
A-Z,a-z - Digits:
0-9 - A handful of symbols:
-_.~
Everything else either needs encoding or has a reserved meaning in URL structure (like /, ?, &, and =).
How Percent-Encoding Works
The rule is straightforward: take the character, convert it to its UTF-8 byte sequence, then represent each byte as %XX where XX is the byte value in hexadecimal.
- Space →
%20(0x20 in hex) &→%26=→%3D?→%3F/→%2F- 「日」(U+65E5) →
%E6%97%A5(3 UTF-8 bytes: 0xE6, 0x97, 0xA5)
Multi-byte characters like Japanese, Chinese, or emoji produce multiple %XX pairs because they require multiple bytes in UTF-8.
URL Encoding in Practice
Query Strings with encodeURIComponent
When building URLs dynamically in JavaScript, always encode individual parameter values with encodeURIComponent():
const query = 'hello world & more';
const url = `/search?q=${encodeURIComponent(query)}`;
// → /search?q=hello%20world%20%26%20more
Multiple Params with URLSearchParams
For multiple parameters, URLSearchParams handles encoding for you automatically — and it's the cleaner approach:
const params = new URLSearchParams({
q: 'hello world',
lang: 'en',
page: '1'
});
const res = await fetch(`/api/search?${params}`);
Form POST Requests
HTML forms submitted with method="POST" and the default application/x-www-form-urlencoded content type encode field values automatically. In this specific format, spaces become + rather than %20 — a quirk you'll encounter when processing form data on the server.
Frequently Asked Questions
- encodeURI vs encodeURIComponent — what's the difference?
encodeURI()is designed for encoding a complete URL. It leaves URL-structural characters like/,?,&,#, and=untouched.encodeURIComponent()is for encoding a single value — it encodes those structural characters too. Rule of thumb: useencodeURIComponent()for query parameter values, andURLSearchParamswhenever you're building query strings.- Is a space %20 or +?
- It depends on context. In URL paths and query strings per RFC 3986, a space is
%20. In the olderapplication/x-www-form-urlencodedformat (used by HTML form POSTs), a space becomes+. If you're unsure which you'll receive on the server side, handle both. UsingURLSearchParamsin JavaScript will always produce+for spaces in query strings — consistent with the form encoding spec. - When do I need to decode a URL?
- Server-side frameworks (Express, Django, Rails, etc.) typically decode URL parameters automatically before you access them, so you rarely need to decode manually. In JavaScript,
decodeURIComponent('%E6%97%A5%E6%9C%AC%E8%AA%9E')returns the original string. You'd need to decode manually if you're parsing raw request strings or working with URL data outside a framework.
Summary
- URL encoding converts unsafe or special characters to
%XXformat using UTF-8 byte values - Use
encodeURIComponent()for query parameter values; useURLSearchParamsfor multiple params - Spaces are
%20in URL paths,+in form-encoded bodies - Most server frameworks decode parameters automatically
Need to encode or decode URLs right now? These tools will save you time:
- URL Encoder — encode any text to percent-encoding format
- URL Decoder — decode %XX sequences back to readable text
- URL Parser — break down a URL into its component parts