/10 min read

What is URL Encoding? A Complete Guide to Percent-Encoding

Every time you search, click a link with special characters, or submit a web form, URL encoding is working behind the scenes. It converts unsafe characters into a format that can travel safely across the internet.

What is a URL?

A URL, or Uniform Resource Locator, is the address of a resource on the internet. Pages, images, API endpoints, files, and downloads all have URLs.

A URL tells the browser where the resource is, what protocol to use, and which extra data, such as query parameters or fragments, should be applied.

For example, https://www.example.com/search?q=hello+world contains a scheme, host, path, and query string.

Anatomy of a URL

A full URL can contain several components:

https://user:pass@www.example.com:443/path/page?key=value&q=test#section
scheme  userinfo      host            port path       query            fragment
ComponentExampleDescription
SchemehttpsProtocol used to access the resource
User infouser:passOptional credentials, rarely used today
Hostwww.example.comDomain name or IP address of the server
Port443Server port, usually implicit for HTTP or HTTPS
Path/path/pageSpecific resource location on the server
Querykey=value&q=testKey-value data after the question mark
Fragment#sectionA page bookmark that is not sent to the server

What is URL Encoding?

URL encoding, also called percent-encoding, converts characters that are unsafe or not allowed in URLs into a safe representation.

The format is a percent sign followed by two hexadecimal digits. A space becomes %20 because its ASCII byte is decimal 32, or hex 20.

Percent-encoding is defined by URI standards such as RFC 3986 and is a core part of how URLs safely carry text.

Before encoding:
  https://example.com/search?q=hello world&lang=en

After encoding:
  https://example.com/search?q=hello%20world&lang=en

Space becomes %20

Why Do We Need URL Encoding?

URL encoding is necessary for several reasons:

  • Reserved characters have meaning - characters like ?, &, =, and # delimit URL parts.
  • Spaces are not allowed directly - URLs need spaces encoded as %20 or sometimes + in form data.
  • Non-ASCII text needs bytes - Thai, Japanese, accented letters, and emoji must be converted to UTF-8 bytes first.
  • Data integrity matters - encoding prevents browsers, proxies, and servers from misreading user data as URL structure.
  • Security depends on context - correct encoding helps prevent parameter injection and broken redirects.

How URL Encoding Works

The process is simple:

  1. Take the character that needs encoding.
  2. Convert it to UTF-8 bytes.
  3. Write each byte as % followed by two uppercase hexadecimal digits.

For ASCII characters, each character is one byte:

Character: space   ASCII: 32   Hex: 20   Encoded: %20
Character: !       ASCII: 33   Hex: 21   Encoded: %21
Character: #       ASCII: 35   Hex: 23   Encoded: %23
Character: @       ASCII: 64   Hex: 40   Encoded: %40

For non-ASCII characters, UTF-8 can produce multiple bytes:

Character: é       UTF-8 bytes: C3 A9          Encoded: %C3%A9
Character: ñ       UTF-8 bytes: C3 B1          Encoded: %C3%B1
Character: 日      UTF-8 bytes: E6 97 A5       Encoded: %E6%97%A5
Character: 😀      UTF-8 bytes: F0 9F 98 80    Encoded: %F0%9F%98%80

Reserved vs Unreserved Characters

RFC 3986 groups URL characters into reserved and unreserved categories.

Unreserved characters

Letters, digits, hyphen, underscore, period, and tilde are safe and usually do not need encoding: A-Z a-z 0-9 - _ . ~

Reserved characters

Characters such as : / ? # [ ] @ ! $ & ' ( ) * + , ; = may have structural meaning. Encode them when they are data, not syntax.

Unsafe or special characters

Spaces, percent signs, quotes, angle brackets, non-ASCII characters, and control characters should be encoded.

Common URL-Encoded Characters

CharacterEncodedCharacterEncoded
space%20!%21
"%22#%23
$%24%%25
&%26'%27
(%28)%29
+%2B,%2C
/%2F:%3A
?%3F=%3D

Encoding Unicode and International Characters

Modern URLs often contain international text. The character is first encoded as UTF-8, then each byte is percent-encoded.

Example: Encoding "café" in a URL

c -> c                    (ASCII, no encoding needed)
a -> a                    (ASCII, no encoding needed)
f -> f                    (ASCII, no encoding needed)
é -> UTF-8 C3 A9 -> %C3%A9

Result: caf%C3%A9
Full URL: https://example.com/search?q=caf%C3%A9

Browsers often show readable characters in the address bar while sending the encoded form in the actual request.

URL Encoding in Programming Languages

Most languages include helpers for URL encoding and decoding:

JavaScript

// Encode a single query parameter value
encodeURIComponent("hello world & goodbye")
// "hello%20world%20%26%20goodbye"

// Decode it back
decodeURIComponent("hello%20world%20%26%20goodbye")
// "hello world & goodbye"

// Encode an entire URI while keeping URL structure intact
encodeURI("https://example.com/path?q=hello world")
// "https://example.com/path?q=hello%20world"

// URLSearchParams handles query encoding automatically
const params = new URLSearchParams({ q: "hello world", lang: "en" });
params.toString();
// "q=hello+world&lang=en"

Python

from urllib.parse import quote, unquote, urlencode

quote("hello world & goodbye")
# 'hello%20world%20%26%20goodbye'

unquote("hello%20world%20%26%20goodbye")
# 'hello world & goodbye'

urlencode({"q": "hello world", "lang": "en"})
# 'q=hello+world&lang=en'

quote("/path/to/resource", safe="/")
# '/path/to/resource'

PHP

// Spaces become %20
rawurlencode("hello world & goodbye");
// "hello%20world%20%26%20goodbye"

// Spaces become + for form-style data
urlencode("hello world & goodbye");
// "hello+world+%26+goodbye"

rawurldecode("hello%20world");  // "hello world"
urldecode("hello+world");       // "hello world"

Java

import java.net.URLEncoder;
import java.net.URLDecoder;
import java.nio.charset.StandardCharsets;

URLEncoder.encode("hello world", StandardCharsets.UTF_8);
// "hello+world"

URLDecoder.decode("hello%20world", StandardCharsets.UTF_8);
// "hello world"

encodeURI vs encodeURIComponent

JavaScript has two similar-looking functions, but they are used for different jobs:

FunctionUse CaseDoes Not Encode
encodeURI()Encoding a complete URL while preserving URL structure: / ? # [ ] @ ! $ & ' ( ) * + , ; =
encodeURIComponent()Encoding a single parameter value or path segment- _ . ~ ! ' ( ) *
const value = "price=10&currency=USD";

// Wrong for parameter values: & and = are not encoded
encodeURI("https://api.com/search?filter=" + value);
// "https://api.com/search?filter=price=10&currency=USD"
// Server sees two parameters: filter=price=10 and currency=USD

// Correct: encode the value as one component
"https://api.com/search?filter=" + encodeURIComponent(value);
// "https://api.com/search?filter=price%3D10%26currency%3DUSD"
// Server sees one parameter: filter=price=10&currency=USD

Rule of thumb

Use encodeURIComponent() for individual values such as query parameters and path segments. Use encodeURI() only for an already assembled full URL.

Common Mistakes with URL Encoding

1. Double encoding

Encoding text that is already encoded turns %20 into %2520 because the percent sign itself becomes %25. Encode once at the boundary where data enters the URL.

2. Using encodeURI for query values

encodeURI does not encode & or =, so user input can accidentally become extra query parameters. Use encodeURIComponent for values.

3. Confusing + and %20

+ means space in application/x-www-form-urlencoded data, but decodeURIComponent does not convert + to a space automatically.

4. Not encoding file names or path segments

File names can contain spaces and special characters. Encode each path segment before inserting it into a URL.

const encoded = encodeURIComponent("hello world");
// "hello%20world"

encodeURIComponent(encoded);
// "hello%2520world"  <-- wrong, % became %25

const value = "hello world";
const url = "/search?q=" + encodeURIComponent(value);
// Encode once at the boundary
// Broken or ambiguous URL
const url = "/files/" + "my report (final).pdf";
// "/files/my report (final).pdf"

// Properly encoded path segment
const url = "/files/" + encodeURIComponent("my report (final).pdf");
// "/files/my%20report%20(final).pdf"

Real-World Examples

URL encoding appears constantly in normal web work:

Google Search

https://www.google.com/search?q=what+is+URL+encoding%3F

Spaces become +
Question mark becomes %3F

API Requests

GET /api/users?name=O%27Brien&city=San%20Francisco

Decoded:
  name = O'Brien
  city = San Francisco

Email Mailto Links

mailto:user@example.com?subject=Hello%20World&body=Hi%2C%20how%20are%20you%3F

Decoded:
  subject = Hello World
  body = Hi, how are you?

Redirect URLs

https://auth.example.com/login?redirect=https%3A%2F%2Fapp.example.com%2Fdashboard%3Ftab%3Dsettings

Decoded redirect value:
  https://app.example.com/dashboard?tab=settings

Encode & Decode URLs Instantly

Use our free URL Encoder & Decoder tool to encode or decode any URL, query parameter, or text right in your browser.

Try URL Encoder & Decoder

References

  1. Berners-Lee, T., Fielding, R., & Masinter, L. (2005). RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax. https://datatracker.ietf.org/doc/html/rfc3986
  2. Berners-Lee, T., Masinter, L., & McCahill, M. (1994). RFC 1738 - Uniform Resource Locators (URL). https://datatracker.ietf.org/doc/html/rfc1738
  3. Mozilla Developer Network. encodeURIComponent() - JavaScript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent
  4. WHATWG. URL Standard. https://url.spec.whatwg.org/
  5. Python Software Foundation. urllib.parse - Parse URLs into components. https://docs.python.org/3/library/urllib.parse.html
USTHJP