What Is URL Encoding? URL Encoding Explained With Examples

Try putting this address in a browser:

https://example.com/search?q=hello world

It works, but only because the browser quietly rewrites it before sending the request. A space isn't allowed to appear as-is in a URL, so what actually goes over the wire is:

https://example.com/search?q=hello%20world

That %20 is URL encoding, also called percent-encoding. It matters most when you build URLs in code: a search term, a name, or a redirect address dropped into a query string without being encoded can silently break the request or change its meaning. This guide explains how percent-encoding works, which characters are involved and why, and how to encode values correctly in JavaScript and PHP.

What Is URL Encoding?

URL encoding represents a character as a % followed by two hexadecimal digits, which stand for the character's byte value. The space character is byte 0x20, so it becomes %20:

hello world  →  hello%20world

The specification that defines this, RFC 3986, calls it percent-encoding. "URL encoding" and "percent-encoding" mean the same thing in everyday use.

Non-ASCII characters are first converted to bytes using UTF-8, and each byte is then percent-encoded. The letter é is two bytes in UTF-8, so it becomes two escapes: café becomes caf%C3%A9. The hexadecimal digits are case-insensitive, so %c3%a9 and %C3%A9 mean the same thing, though uppercase is the convention.

Why Do URLs Need Encoding?

A URL has structure, and certain characters act as punctuation that marks the boundaries between its parts. Look at this one:

https://example.com/search?q=hello&sort=date
  • ? starts the query string
  • & separates one parameter from the next
  • = separates a parameter's name from its value
  • # starts the fragment
  • / separates path segments
  • % introduces an encoded character

Because these characters have structural meaning, a problem appears when one of them is part of your data rather than the URL's structure. RFC 3986 says that if data "would conflict with a reserved character's purpose as a delimiter, then the conflicting data must be percent-encoded before the URI is formed." A parser can't guess whether an & is a separator or part of a value, so you have to say which by encoding it.

URL Encoding Example

Suppose a user searches for red & blue. Encoded, it becomes:

red%20%26%20blue

and the full URL is:

https://example.com/search?q=red%20%26%20blue

Now compare what happens if you skip the encoding and write q=red & blue. A parser sees the & and starts a new parameter, so it reads two parameters — q with the value "red ", and a second parameter named " blue" with no value at all. The search term is silently cut off. With %26, the parser reads one parameter, q, whose value is exactly red & blue.

Common URL Encoded Characters

CharacterEncoded
Space%20
&%26
=%3D
?%3F
#%23
%%25
+%2B
/%2F

Space and + deserve a closer look. %20 is the percent-encoded form of a space, and it works everywhere in a URL. A + meaning "space" is a different convention, used by application/x-www-form-urlencoded, the format HTML forms use to submit data and that query strings are commonly parsed with. It is not part of RFC 3986. So in a query string, q=hello+world is normally read as hello world, but in a URL path, a + is just a literal plus sign. If you actually mean a plus sign in a value, you must encode it as %2B.

Reserved vs Unreserved Characters

RFC 3986 splits characters into two groups.

Unreserved characters can appear anywhere in a URL and don't normally need encoding:

A–Z  a–z  0–9  -  .  _  ~

Reserved characters are the ones that can act as delimiters:

:  /  ?  #  [  ]  @      (general delimiters)
!  $  &  '  (  )  *  +  ,  ;  =      (sub-delimiters)

What matters is that whether a reserved character needs encoding depends on where it appears. It doesn't always need it. A / is normal punctuation between path segments, but it would need encoding as %2F if it were part of a single segment's name. A : is fine after the scheme and in host:port. Even / and ? are technically allowed inside a query string. The rule is: encode a character when, in that position, it would otherwise be read as structure instead of data. In practice, most encoding functions take the safe route and encode all of them when you're encoding a value.

URL Encoding vs URL Decoding

Encoding turns text into a form that's safe to place inside a URL. Decoding reverses it:

Encode:  hello world   →  hello%20world
Decode:  hello%20world →  hello world

You encode when building a URL — assembling a request or a link from data. You decode when reading one — turning a parameter you received back into the original text, or making a messy encoded URL readable while debugging.

URL Encoding Query Parameters and API Requests

Query strings are where encoding matters most. In this URL, the parameter q has the value red shoes:

https://example.com/search?q=red%20shoes

Typical API requests follow the same pattern:

GET /users?name=John%20Doe

GET /api/products?search=red%20shoes&category=men

A trickier value is C++ developer. Encoded correctly, the plus signs become %2B:

GET /api/search?q=C%2B%2B%20developer

If you wrote q=C++ developer instead, a server that parses the query as form-encoded data would turn each + into a space and read the value as C   developer — the "C++" is lost. This is a good reason to always encode values programmatically rather than by hand.

The same applies to structured data. If you pass JSON in a query parameter, the braces, quotes, and colons all need encoding: {"a":1} becomes %7B%22a%22%3A1%7D. (For more on that format, see our JSON guide.)

Encoding a Full URL vs Encoding a Parameter

A very common mistake is encoding an entire URL when only one value needed encoding. Different parts of a URL follow different rules, so the right function depends on what you're encoding.

Take https://example.com/search?q=hello world. Only hello world needs encoding. If you encode the whole string as if it were a single value, you get:

https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world

That's no longer a usable URL: the :, /, ?, and = that gave it structure were all encoded away. The right approach is to encode each value and then assemble the URL around it.

The reverse mistake also happens: using a function meant for whole URLs on a value. JavaScript's encodeURI() leaves structural characters alone, including &, so encodeURI("https://example.com/search?q=red & blue") produces q=red%20&%20blue — the & is still there and still splits the parameter.

There is one legitimate case for encoding a whole URL: when that URL is itself the value of another URL's parameter, such as a redirect target. Then https://example.com/a?b=c&d=e becomes https%3A%2F%2Fexample.com%2Fa%3Fb%3Dc%26d%3De so it travels as a single value.

URL Encoding in JavaScript

For an individual query parameter value, use encodeURIComponent():

const value = "red & blue shoes";
const encoded = encodeURIComponent(value);

console.log(encoded);
// red%20%26%20blue%20shoes

console.log(decodeURIComponent(encoded));
// red & blue shoes

encodeURIComponent() encodes everything except letters, digits, and - _ . ! ~ * ' ( ), which makes it the right choice for a value going inside a query string. encodeURI() is for a complete address and additionally leaves ; , / ? : @ & = + $ # untouched.

Two behaviors to know: decodeURIComponent() throws a URIError ("URI malformed") if it meets a stray % that isn't followed by two valid hex digits, and it does not turn + into a space. If you build URLs with URLSearchParams or the URL object, encoding is handled for you — but it uses the form-encoded convention, so spaces come out as +: new URLSearchParams({ q: "red & blue" }) serializes to q=red+%26+blue, which is equivalent when read as a query string.

URL Encoding in PHP

$query = 'red & blue shoes';

echo urlencode($query);
// red+%26+blue+shoes

echo rawurlencode($query);
// red%20%26%20blue%20shoes

PHP has two functions, and they differ mainly in how they treat spaces. urlencode() follows the form-encoded convention (spaces become +), while rawurlencode() follows RFC 3986 (spaces become %20). They also differ on ~: urlencode() turns it into %7E, rawurlencode() leaves it alone. The decoding pair mirrors this — urldecode() turns + into a space, rawurldecode() doesn't.

A practical rule: use http_build_query() to build a whole query string (it uses + by default, or %20 if you pass PHP_QUERY_RFC3986), and rawurlencode() for a path segment, where a + would be read as a literal plus sign rather than a space.

Common URL Encoding Mistakes

1. Encoding the wrong part. Encoding an entire URL instead of just the parameter value breaks the URL's structure, as shown above.

2. Double encoding. Encoding a value that is already encoded turns the % itself into %25, so %20 becomes %2520:

hello world  →  hello%20world  →  hello%2520world

The server decodes once and gets the literal text hello%20world instead of a space. RFC 3986 states that implementations "must not percent-encode or decode the same string more than once." If you see %25 in a URL where you expected a plain escape, that's the sign. (In PHP, double-applying urlencode() gives a different-looking result — %2B — because the first pass turns spaces into +.)

3. Treating + and %20 as universally interchangeable. They mean the same thing in form-encoded query strings, but in a path a + is a literal plus.

4. Not encoding & inside a value. The parser will start a new parameter partway through your data.

5. Mixing up URL encoding and HTML encoding. They solve different problems. URL encoding turns & into %26; HTML encoding turns it into &. Applying the wrong one gives you garbage. The two even meet in one place: when you write a URL with several parameters inside an HTML href, the separators are conventionally written as & in the source, and the browser turns them back into plain & before requesting the URL.

URL Encoding vs HTML Encoding vs Base64

Three "encodings" get confused constantly, each solving a different problem:

MethodPurposeExample: a b&c
URL encodingSafely represent data in URL syntaxa%20b%26c
HTML encodingRepresent special characters safely in HTMLa b&c
Base64Represent binary or text data using 64 printable charactersYSBiJmM=

None of them is encryption. There's also a real connection between URL encoding and Base64: standard Base64 uses +, /, and =, all of which are special in URLs, so putting Base64 in a URL means percent-encoding it or using the URL-safe Base64 variant (which JSON Web Tokens use — see our JWT guide). For how Base64 itself works, see our Base64 encoding guide.

How to Encode and Decode URLs With Kravoy

Kravoy's URL Encoder / Decoder converts text in your browser. To use it:

  1. Open the URL Encoder / Decoder and choose Encode or Decode.
  2. Choose the mode. Component is for a single value going into a query string and encodes everything, including & ? / : #. Full URI is for a whole address and leaves those structural characters alone so the URL stays valid.
  3. Paste your text, URL, or parameter value.
  4. Review the result, then copy it.

The two modes correspond to JavaScript's encodeURIComponent() and encodeURI(), so results follow those functions — spaces come out as %20, not +. If you try to decode text containing a stray %, the tool tells you the input isn't validly encoded rather than failing silently.

URL Encoding Checklist

  • Identify which part of the URL you're encoding — a path segment, a query value, or a whole address.
  • Encode parameter values, not the whole URL.
  • Be careful with reserved characters — whether one needs encoding depends on where it appears.
  • Don't double-encode values that are already encoded.
  • Know the difference between %20 and + in context.
  • Don't confuse URL encoding with HTML encoding.
  • Decode a value once, when you're ready to interpret it.
  • Test complex parameters — especially ones containing &, +, =, or non-English characters.

Frequently Asked Questions

What is URL encoding?

A way of representing characters that aren't safe or allowed in a URL as a % followed by two hexadecimal digits, so data can be included in a URL without being mistaken for URL structure.

Why does a space become %20?

A space is byte 0x20, and percent-encoding writes a byte as % plus its hex value. In query strings you may also see a space written as +, which is a separate form-encoding convention.

What does %26 mean?

It's the encoded form of the ampersand (&). Because & separates query parameters, a literal ampersand inside a value has to be written as %26.

What is the difference between URL encoding and percent encoding?

In practice, none — they're two names for the same thing. "Percent-encoding" is the term used in the RFC 3986 specification.

Is + the same as %20?

Not always. In form-encoded query strings both mean a space, but the + convention isn't part of the core URL specification, and in a URL path a + is a literal plus sign.

What is URL decoding?

The reverse of encoding: converting %XX sequences back into the characters they represent, such as hello%20world back into hello world.

Why does %2520 appear in a URL?

Because a value that was already encoded (%20) was encoded a second time: the % became %25, producing %2520. Find where the value is being encoded twice and remove one pass.

Should I encode the entire URL?

Usually not. Encode individual values — such as each query parameter — and assemble the URL around them. Encoding the whole thing destroys the characters that give the URL its structure, unless that URL is itself a value inside another URL.

Recent Articles