A URL can contain only a limited set of characters (letters, digits, -, _, ., ~, and a few others). Other characters—spaces, Cyrillic, and special characters—must be encoded as %XX, where XX is the character’s hexadecimal code. This article explains when and how to encode, how encodeURIComponent and encodeURI differ, and common mistakes.
Use the URL Encoder on reChecker to encode and decode URLs.
Why encode URLs
Spaces and special characters
A space is not allowed in a URL. It is encoded as %20 or + (in application/x-www-form-urlencoded). Characters such as &, =, ?, and # have special meaning—encoding them prevents the URL from being parsed incorrectly.
Cyrillic and Unicode
URLs are historically based on ASCII. Characters outside ASCII (Cyrillic, ideographs, and diacritics) are encoded in UTF-8, and each byte is represented as %XX:
"Привет" → %D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82Modern browsers display Unicode in the address bar, but use the percent-encoded form when sending requests.
Reserved characters
In some contexts, characters such as !$&'()*+,;=:@ are allowed without encoding (RFC 3986), but they are often encoded when used in query parameters for reliability.
encodeURIComponent vs encodeURI
JavaScript has two functions. They differ in which characters they encode.
encodeURIComponent
Encodes almost everything except A-Z a-z 0-9 - _ . ! ~ * ' ( ). It is intended for parameter values, not for an entire URL.
encodeURIComponent('a & b = c');
// "a%20%26%20b%20%3D%20c"
encodeURIComponent('Привет');
// "%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82"Use it for each parameter individually:
const query = 'поиск';
const url = `https://example.com/search?q=${encodeURIComponent(query)}`;
// https://example.com/search?q=%D0%BF%D0%BE%D0%B8%D1%81%D0%BAencodeURI
Encodes only characters that are not allowed in a URL, but does not encode ; , / ? : @ & = + $ #. It is intended for an entire URL, not for its components.
encodeURI('https://example.com/path?name=Иван');
// "https://example.com/path?name=%D0%98%D0%B2%D0%B0%D0%BD"If you apply encodeURIComponent to an entire URL, the slashes and protocol will be broken:
encodeURIComponent('https://example.com/path');
// "https%3A%2F%2Fexample.com%2Fpath" — невалидный URLComparison
| Function | Encodes | Use |
|---|---|---|
| encodeURIComponent | Everything except letters, digits, -_.!~*'() | Query parameter values, fragment |
| encodeURI | Only characters not allowed in a URL | Entire URL (path + query already formed) |
Decoding
decodeURIComponent('%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82');
// "Привет"
decodeURI('https://example.com/path?name=%D0%98%D0%B2%D0%B0%D0%BD');
// "https://example.com/path?name=Иван"Use decodeURIComponent for parameter values. Use decodeURI for an entire URL.
application/x-www-form-urlencoded
When submitting forms with Content-Type: application/x-www-form-urlencoded, spaces are encoded as +, not %20. When parsing on the server, + is decoded as a space. In encodeURIComponent, a space becomes %20. For compatibility with forms, you can replace:
function encodeFormValue(str) {
return encodeURIComponent(str).replace(/%20/g, '+');
}Most modern APIs and fetch using URLSearchParams use %20, and servers handle both forms correctly.
Common mistakes
Encoding an entire URL
// Неправильно
const url = encodeURIComponent('https://example.com/search?q=test');
// Правильно
const base = 'https://example.com/search';
const url = `${base}?q=${encodeURIComponent('test')}`;Double encoding
If a value is already encoded, encoding it again will produce an incorrect result:
encodeURIComponent('%D0%9F%D1%80%D0%B8%D0%B2%D0%B5%D1%82');
// "%25D0%259F%25D1%2580%25D0%25B8%25D0%25B2%25D0%25B5%25D1%2582" — двойное кодированиеCheck the data source. A value received from another API may already be encoded.
Encoding a parameter name
Parameter names must also be encoded if they contain special characters:
const params = { 'user name': 'Иван' };
const query = Object.entries(params)
.map(([k, v]) => `${encodeURIComponent(k)}=${encodeURIComponent(v)}`)
.join('&');
// user%20name=%D0%98%D0%B2%D0%B0%D0%BDURLSearchParams
This modern API for working with query strings encodes values automatically:
const params = new URLSearchParams();
params.set('q', 'поиск');
params.set('page', '1');
params.toString();
// "q=%D0%BF%D0%BE%D0%B8%D1%81%D0%BA&page=1"Using URLSearchParams is recommended instead of manual concatenation—it reduces the chance of errors.
Practical recommendations
- Query parameters — always encode values using
encodeURIComponentorURLSearchParams - Path segments — if a segment contains special characters or Cyrillic, encode each segment separately
- Verification — use the URL Encoder on reChecker to check that the encoding is correct
- Server — make sure the backend decodes parameters correctly (many frameworks do this automatically)
- Redirects — when generating URLs for 302/301, encode all dynamic parts
Correct URL encoding prevents errors when transmitting Cyrillic, spaces, and special characters. The URL Encoder helps you quickly check and generate correctly encoded strings.
Special characters in the path
Path segments allow letters, digits, and a limited set of characters: -, ., _, ~. A slash, /, separates segments and is not encoded within a path. When generating dynamic paths (for example, from a filename), encode each segment:
const filename = 'документ (1).pdf';
const path = `/files/${encodeURIComponent(filename)}`;Encoding in different languages
- PHP:
rawurlencode()for paths and parameter values (space →%20),urlencode()for form data (space →+) - Python:
urllib.parse.quote()withsafeto specify characters that should not be encoded - Java:
URLEncoder.encode()for form data; for paths, useURIorURLwith correct parsing
Checking the result with the URL Encoder on reChecker helps verify correctness when working with different stacks.
Punycode for international domains
Domains containing Cyrillic characters (for example, сайт.рф) are encoded in Punycode (xn--80aswg.xn--p1ai). Browsers display Unicode, but Punycode is used for DNS resolution and in headers. In JavaScript, url.domainToASCII() and url.domainToUnicode() are used to encode/decode Punycode.
Encoding in fetch and XMLHttpRequest
When passing parameters to fetch, use URLSearchParams or encode the values manually:
const params = { q: 'поиск', page: 1 };
const query = new URLSearchParams(params).toString();
fetch(`/api/search?${query}`);For POST requests with application/x-www-form-urlencoded, the request body must also be encoded. URLSearchParams does this automatically when passed to body.
Server-side handling
Servers and frameworks usually decode parameters automatically. Check the settings: some proxies or CDNs may change the encoding. When parsing a query string manually, use built-in parsers (URL, URLSearchParams)—they handle edge cases correctly.