1. What Is URL Encoding?
URL encoding, more precisely called percent-encoding, is the mechanism used to represent characters and bytes in a URI or URL when those characters cannot safely appear in a particular URL component in their literal form.
A percent-encoded byte is written as a percent sign followed by two hexadecimal digits. For example:
RFC 3986 defines percent-encoding as a way to represent an octet inside a URI component when the corresponding character is outside the permitted set or would conflict with the component's syntax.
This distinction is important because a URL is not simply one unrestricted text string. It contains components with different meanings, including the scheme, authority, path, query and fragment. A character that is structural in one context can represent ordinary data in another.
For example:
contains URL syntax as well as data. The ? introduces the query, & separates parameters, and = separates a parameter name from its value.
When a literal & is actually part of a parameter value, it generally needs to be encoded so that it is not mistaken for the next parameter delimiter.
That is why a URL encoder / decoder should be context-aware rather than simply replacing a few characters everywhere.
2. Percent-Encoding Syntax: %HH
The basic percent-encoding unit has this structure:
where H represents a hexadecimal digit (0–9, A–F). Examples include:
%20(space)%23(# fragment anchor)%26(& delimiter)%2F(/ forward slash)%C3%A9(UTF-8 byte sequence for é)
The first examples correspond to ASCII characters, while %C3%A9 represents the UTF-8 byte sequence used for é.
RFC 3986 defines the syntax as % followed by exactly two hexadecimal digits. It also states that hexadecimal letters are case-insensitive, although producers should use uppercase hexadecimal digits for consistency.
Therefore, %2F and %2f represent the same percent-encoded octet, although %2F is the cleaner canonical presentation.
A malformed sequence such as %2, %G0, or %ZZ is not a valid percent-encoding triplet. The calculator explicitly validates malformed percent sequences rather than silently deleting or inventing characters.
3. Reserved and Unreserved URL Characters
RFC 3986 divides URI characters into important classes:
Unreserved Characters
The unreserved set consists of:
These characters do not have a reserved structural purpose in the generic URI syntax. RFC 3986 says URI producers should not unnecessarily percent-encode them.
Reserved Characters
The reserved set consists of:
These characters can serve as delimiters or have special meaning within URI syntax.
However, reserved does not mean “always encode.” Whether a reserved character needs percent-encoding depends on the component and whether the character is acting as syntax or as data. RFC 3986 explicitly makes this component-sensitive distinction.
For example, https://example.com/a/b uses / structurally in the path. But if / is part of an individual query parameter value, encoding it as %2F may be necessary to preserve its literal data meaning.
This is one of the main reasons encodeURI() and encodeURIComponent() are not interchangeable.
4. Why Spaces Become %20
Under RFC 3986-style percent-encoding, a space is represented as:
The reason is straightforward: the space character is not part of the normal unreserved URI character set. RFC 3986 gives %20 as the canonical percent-encoding example for the ASCII space octet.
The important exception is form-style URL encoding, where spaces are commonly represented using +. That means:
in application/x-www-form-urlencoded serialization.
The WHATWG URL Standard explicitly defines the form-urlencoded percent-encode set and its spaceAsPlus behavior. MDN's documentation for URLSearchParams likewise states that spaces are serialized as +.
So:
- RFC-style:
hello%20world - Form-style:
hello+world
These should not be treated as accidental spelling variations. They belong to different encoding conventions.
5. %20 and + Are Not Always Interchangeable
A particularly common URL bug involves a literal plus sign. Consider:
The correct query-component representation is:
because the literal + characters need to survive as data.
If a form/query parser interprets a raw + as a space, an input such as C++ can accidentally be interpreted as C .
That is precisely why blindly feeding raw query strings through generic parameter APIs can produce surprising results. MDN documents this behavior for URLSearchParams: when parsing a string, it interprets + as a space because it follows the application/x-www-form-urlencoded convention.
The calculator was specifically tested for this failure mode. Its query-parameter editor now preserves literal plus signs in non-form modes and serializes spaces according to the selected encoding mode.
6. encodeURI() vs encodeURIComponent()
JavaScript provides two commonly used functions that are easy to confuse:
They serve different purposes:
- encodeURI(): Intended for a complete URI and therefore preserves characters that are meaningful for URI structure. For example, the delimiters in
https://example.com/search?q=testmust generally remain recognizable as URI structure. - encodeURIComponent(): Intended for an individual component such as a query value, path segment, or parameter value. It encodes a much larger set of characters so that the result can safely represent one component rather than an entire structured URI.
Suppose the value is hello world & C++. As a query-component value, the data should not be allowed to become accidental URL syntax.
The production calculator explicitly tests and distinguishes these modes rather than treating them as interchangeable functions.
7. Example: Encoding a Query Parameter Correctly
Consider:
A percent-encoded query component becomes:
Now consider category=dev tools, which becomes category=dev%20tools. And tags=c++ becomes tags=c%2B%2B.
The complete query can therefore be:
Notice the two different roles of &:
Here & is structural because it separates parameters. If & were part of a parameter value, it would instead be encoded as %26.
This is the practical reason that encoding the component is different from encoding the entire URL.
8. How a URL Is Structured
A typical URL can be viewed as:
For example:
can be conceptually divided into:
- Scheme:
https: - Hostname:
api.example.com - Path:
/v1/search - Query:
query=hello%20world - Fragment:
#results
A port can appear after the host, such as https://example.com:8443/. RFC 3986 defines these generic URI components and the delimiters separating them.
The calculator's live URL breakdown is designed around this structure and independently verifies protocol, hostname, explicit port, pathname, query and fragment extraction.
9. Query Strings and Parameter Encoding
The query component is introduced by ?. For example:
contains two common key-value parameters: q=shoes and color=black. The & separates them and = separates each name from its value.
When a query value contains characters that might be interpreted as delimiters, those characters should be encoded as data. For example:
should not be serialized naively as search=shoes & boots because the ampersand can be interpreted as a parameter separator. A safer encoded value is search=shoes%20%26%20boots.
The interactive parameter editor on this calculator is specifically designed to make this distinction visible instead of requiring users to construct query strings manually.
10. Duplicate Query Parameters Are Valid Data
Not every query string behaves like a simple JavaScript object. This is completely valid:
The same parameter name appears multiple times. An implementation that converts everything immediately to a simple { key: value } object can accidentally collapse duplicate values.
The calculator therefore preserves duplicate query parameters and tests their ordering and serialization behavior. This matters for APIs, search interfaces, filters and other systems where repeated parameters have deliberate semantics. Do not assume a=1&a=2 is automatically equivalent to a=2. The interpretation belongs to the receiving application or protocol.
11. URL Encoding and UTF-8
Percent-encoding ultimately represents bytes, so non-ASCII text needs a character-to-byte encoding step. For modern web applications, UTF-8 is the critical encoding to understand.
For example:
- é is represented in UTF-8 by bytes
C3 A9→ percent-encoded as%C3%A9 - € uses bytes
E2 82 AC→ becomes%E2%82%AC - 😀 (grinning face) uses bytes
F0 9F 98 80→ becomes%F0%9F%98%80
RFC 3986 recommends that textual data from the Unicode character set be converted to UTF-8 octets before percent-encoding the octets that need representation in URI syntax.
The calculator's Unicode regression suite explicitly tests accented characters, euro signs, CJK text, Devanagari, Arabic, Cyrillic, emoji and supplementary Unicode characters.
12. What Is Double URL Encoding?
Double encoding happens when a value that has already been percent-encoded is encoded again.
If the already encoded value is treated as literal input and encoded again, the % itself becomes %25: hello%2520world.
This is not necessarily a calculator error. It can be the mathematically expected result when the input really is the literal string hello%20world. The problem occurs when an application unintentionally encodes the same logical data twice.
RFC 3986 specifically warns against repeatedly encoding or decoding the same URI string because doing so can change how percent signs are interpreted.
A practical debugging rule is:
Do not repeatedly apply encoding simply because the string still contains percent signs.
13. Decoding Must Respect URL Structure
Decoding is not always safely performed by globally replacing every %XX sequence before parsing the URL. Suppose a percent-encoded value represents a reserved delimiter. Decoding it too early can change the interpretation of the URL.
RFC 3986 explains that the components and subcomponents should be identified before percent-encoded octets are safely decoded, because decoding first can cause encoded data to be mistaken for URI delimiters.
This is particularly important for full URLs. For example, a percent-encoded question mark inside data (%3F) must not suddenly become a structural ? before the application has determined which URL component the value belongs to.
The calculator therefore distinguishes full-address decoding from component decoding.
14. RFC 3986 Strict Mode
A strict RFC 3986-oriented encoder is useful when you need predictable percent-encoding based on URI syntax rather than the behavior of a form serializer. Important principles include:
- Unreserved:
A-Z a-z 0-9 - . _ ~ - Percent encoding:
%HH - Canonical hexadecimal presentation: uppercase
%A-F - Reserved characters remain context-sensitive
The standard should therefore be used as a syntax model, while the application layer determines which component is being encoded. This is why a URL path, a query value and an entire URL should not necessarily receive identical transformations.
The calculator's strict mode was independently tested against reserved and unreserved character classes, percent sequences and Unicode.
15. Form Encoding and URLSearchParams
Modern web developers frequently encounter a different convention through URLSearchParams.
URLSearchParams follows the application/x-www-form-urlencoded serialization rules when converting its parameter collection to a string. In this representation, spaces become +, and additional characters can receive percent-encoding according to the form-urlencoded percent-encode set.
For example:
new URLSearchParams([ ["q", "hello world"] ]).toString() // produces: "q=hello+world"
That differs from manually constructing a query with an RFC-style %20 convention. This difference is one reason developers can see a URL apparently “change itself” after manipulating its query parameters.
MDN documents this distinction between URL.search and serialized URLSearchParams, including the different treatment of spaces and other characters.
16. URL Encoding Is Not Security
Encoding changes representation. It does not automatically make input trustworthy.
Percent-encoding can prevent characters from interfering with a URL's syntax, but it does not by itself prevent:
For example, encoding <script>alert(1)</script> does not magically make a web application secure. The receiving system may decode the value later, and the correct security control must be applied in the actual processing context.
Similarly, URL encoding does not validate whether a redirect target is trustworthy, whether a hostname is allowed for an outbound request, or whether a database query is safely parameterized.
The calculator's security material explicitly preserves this distinction. Google's guidance also emphasizes accurate, trustworthy explanations rather than unsupported security claims.
17. Double Encoding and Open Redirect Problems
Two practical URL bugs deserve special attention:
Double Encoding
An application may encode a % character that was already introduced by a previous encoding stage: %20 → %2520. This can cause broken routing or incorrect parameter values.
Open Redirects
A URL encoder does not determine whether a redirect destination is safe. An application that accepts ?next=https://attacker.example must validate the destination according to its security requirements. Encoding the parameter does not solve that architectural problem.
The URL calculator can help you represent the data correctly, but the application must still enforce its own destination policy.
18. URL Encoding vs Base64
URL percent-encoding and Base64 solve different problems:
- Percent-encoding represents bytes using
%HHsequences so that data can be placed safely within URI syntax. - Base64 represents binary data using a 64-character alphabet.
If your problem is putting a parameter value into a URL, percent-encoding is generally the relevant operation. When binary data needs to be represented as text rather than placed into a URL component, the Base64 Encoder / Decoder is a more appropriate tool.
The two techniques can also appear together in larger systems, but they should not be treated as interchangeable encoding systems.
19. Practical JavaScript Examples
const value = "hello world & C++"; const encoded = encodeURIComponent(value); console.log(encoded); // "hello%20world%20%26%20C%2B%2B"
const decoded = decodeURIComponent(encoded); console.log(decoded); // "hello world & C++"
const url = "https://example.com/search?q=hello world"; const encoded = encodeURI(url); console.log(encoded); // "https://example.com/search?q=hello%20world"
const params = new URLSearchParams();
params.set("query", "hello world");
params.set("category", "dev tools");
console.log(params.toString()); // "query=hello+world&category=dev+tools"Remember that URLSearchParams follows form-urlencoded serialization rules, including + for spaces. For an individual query value, use component encoding rather than encoding the complete URL.
20. Python Examples
Python's standard library provides URL parsing and quoting functionality through urllib.parse:
from urllib.parse import quote, unquote
encoded = quote("hello world & C++", safe="")
decoded = unquote(encoded)
print(encoded) # "hello%20world%20%26%20C%2B%2B"
print(decoded) # "hello world & C++"For form-style query data, Python also provides quote_plus():
from urllib.parse import quote_plus
encoded = quote_plus("hello world")
print(encoded) # "hello+world"The distinction matters because quote_plus() uses + for spaces, while the generic quoting behavior can use %20. Use the function that matches the format expected by the receiving system rather than choosing one merely because both are called “URL encoding.”
21. PHP Examples
PHP provides both generic and form-style URL functions:
// RFC 3986 encoding (space as %20)
$encoded = rawurlencode("hello world & C++");
$decoded = rawurldecode($encoded);
// Form-style query data (space as +)
$form_encoded = urlencode("hello world");
$form_decoded = urldecode($form_encoded);These functions are useful precisely because URL encoding is context-sensitive. The distinction between rawurlencode() and urlencode() should not be erased when explaining the behavior.
For IP addressing and CIDR planning rather than URL syntax, use the IP Subnet Calculator.
22. How to Use This URL Encoder / Decoder
- Enter the original value.
- Select the query/component mode.
- Encode.
- Copy the resulting value.
- Enter the full URL.
- Select full-address encoding.
- Encode the URL while preserving its structural delimiters.
- Inspect protocol, hostname, port, path, query and fragment.
- Select Decode.
- Paste the percent-encoded value.
- Select the appropriate decoding mode.
- Decode once.
- Verify that the resulting text is what you expect.
For multiple parameters, use the query parameter editor rather than manually assembling a long query string. The calculator supports adding, deleting, enabling, disabling and editing parameters and preserves duplicate keys.
For repeated lines of data, batch mode can process each line independently.
Frequently Asked Questions
Technical Notes
Percent Encoding Is Component-Specific
A URL should not be treated as an undifferentiated string. Encoding rules depend on whether you are handling a complete URL, scheme, host, path, path segment, query, parameter name, parameter value, or fragment. That is why this calculator exposes multiple encoding modes instead of one generic replace button. RFC 3986 explicitly describes URI components and context-sensitive use of reserved characters.
+ Is Especially Context-Sensitive
Do not automatically replace %20 ↔ + in every URL. The + space convention is associated with form-urlencoded serialization, while RFC 3986 percent-encoding uses %20 for a space. WHATWG and MDN document the form-urlencoded behavior separately.
Decode Once at the Correct Boundary
An application should parse the URL structure before decoding values where necessary. Otherwise an encoded delimiter can become an actual delimiter and change how the URL is interpreted.
Encoding Does Not Sanitize
Percent-encoding is a representation operation. Security validation must occur separately in the application context where the data is consumed.
Standards & References
The primary reference for generic URI syntax, percent-encoding, reserved characters, unreserved characters, URI components and normalization.
Defines current web-platform URL parsing and serialization behavior, including the application/x-www-form-urlencoded percent-encode set and space-as-plus serialization.
Documents browser behavior for parsing and serializing query parameters, including + as the serialized representation of spaces in form-urlencoded data.
Use the browser's encodeURI(), encodeURIComponent(), decodeURI() and decodeURIComponent() APIs according to whether the value is a complete URI or an individual component.