100% Private

URL Encoding Explained: Percent Encoding for Web Developers

A complete guide to URL encoding covering why it's necessary, how percent encoding works, and the difference between encodeURI and encodeURIComponent.

Why URL Encoding is Needed

URLs can only contain a limited set of characters from the ASCII character set. When you need to include special characters, spaces, or non-ASCII characters (like Unicode) in a URL, they must be encoded.

Without Encoding

❌ https://toolsdock.com/search?q=hello world&lang=日本語
   Problem: space breaks URL, non-ASCII characters may fail

With Encoding

✅ https://toolsdock.com/search?q=hello%20world&lang=%E6%97%A5%E6%9C%AC%E8%AA%9E
   All characters are safe ASCII

What Happens Without Encoding?

  • Broken URLs: Browsers may not navigate correctly
  • Data loss: Special characters may be misinterpreted
  • Security issues: Unencoded characters can enable injection attacks
  • Server errors: Web servers may reject malformed URLs

How Percent Encoding Works

Percent encoding (also called URL encoding) replaces unsafe characters with a percent sign (%) followed by two hexadecimal digits representing the character's byte value.

Encoding Process

  1. Convert the character to its UTF-8 byte sequence
  2. Convert each byte to two hexadecimal digits
  3. Prefix each pair with a percent sign

Examples

CharacterUTF-8 BytesPercent Encoded
Space0x20%20
&0x26%26
=0x3D%3D
?0x3F%3F
é0xC3 0xA9%C3%A9
0xE4 0xB8 0xAD%E4%B8%AD

Special Case: Space

Spaces can be encoded as %20 or +, but they're not interchangeable:

  • %20 is the standard percent encoding
  • + is only valid in query string values (application/x-www-form-urlencoded)
// In URL path: only %20 is correct
https://toolsdock.com/my%20file.pdf ✅
https://toolsdock.com/my+file.pdf   ❌ (+ is a literal plus)

// In query string: both work
?name=John%20Doe ✅
?name=John+Doe    ✅

Safe vs Reserved Characters

Unreserved (Safe) Characters

These never need encoding:

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

Reserved Characters

These have special meaning in URLs and must be encoded if used literally:

CharacterPurpose in URLEncoded
:Scheme separator (https:)%3A
/Path separator%2F
?Query string start%3F
#Fragment identifier%23
&Query parameter separator%26
=Key-value separator%3D
@User info separator%40

Context Matters

// & in query string - don't encode (it's a separator)
?name=John&age=30

// & in a value - must encode
?company=Johnson%26Johnson

// / in path - don't encode (it's a separator)
/users/123/profile

// / in a value - must encode
?path=%2Fusers%2F123

encodeURI vs encodeURIComponent

JavaScript provides two encoding functions with different purposes:

encodeURI()

Use for encoding a complete URL. Preserves URL structure characters.

const url = "https://toolsdock.com/path with spaces?q=hello world";
encodeURI(url);
// "https://toolsdock.com/path%20with%20spaces?q=hello%20world"

// Preserved: : / ? & = #

Does NOT encode: A-Z a-z 0-9 ; , / ? : @ & = + $ - _ . ! ~ * ' ( ) #

encodeURIComponent()

Use for encoding a URL component (query parameter value, path segment).

const value = "hello?world&foo=bar";
encodeURIComponent(value);
// "hello%3Fworld%26foo%3Dbar"

// All special characters are encoded

Does NOT encode: A-Z a-z 0-9 - _ . ! ~ * ' ( )

Comparison

CharacterencodeURIencodeURIComponent
Space%20%20
?? (unchanged)%3F
&& (unchanged)%26
== (unchanged)%3D
// (unchanged)%2F
## (unchanged)%23

When to Use Each

// Building a URL with user input in query params
const search = "cats & dogs";
const url = "https://toolsdock.com/search?q=" + encodeURIComponent(search);
// https://toolsdock.com/search?q=cats%20%26%20dogs ✅

// Wrong: encodeURI won't encode the &
const badUrl = "https://toolsdock.com/search?q=" + encodeURI(search);
// https://toolsdock.com/search?q=cats%20&%20dogs ❌
// The & breaks the query string!

Common Scenarios

1. Building Query Strings

// Safe way to build query strings
function buildQueryString(params) {
  return Object.entries(params)
    .map(([key, value]) =>
      encodeURIComponent(key) + '=' + encodeURIComponent(value)
    )
    .join('&');
}

const params = {
  search: "hello world",
  filter: "price<100",
  category: "food&drinks"
};

buildQueryString(params);
// "search=hello%20world&filter=price%3C100&category=food%26drinks"

// Or use URLSearchParams (modern browsers)
const searchParams = new URLSearchParams(params);
searchParams.toString();
// Same result, handles encoding automatically

2. Embedding URLs in URLs

// Redirect URL that contains another URL
const returnUrl = "https://mysite.com/callback?token=abc123";
const loginUrl = "https://toolsdock.com/login?redirect="
                 + encodeURIComponent(returnUrl);

// Result:
// https://auth.toolsdock.com/login?redirect=https%3A%2F%2Fmysite.com%2Fcallback%3Ftoken%3Dabc123

3. Path Segments with Special Characters

// File name with spaces
const filename = "My Document (Final).pdf";
const url = "/files/" + encodeURIComponent(filename);
// /files/My%20Document%20(Final).pdf

4. Form Data

// Standard form encoding (application/x-www-form-urlencoded)
// Spaces become + instead of %20
const formData = "name=John+Doe&message=Hello+World";

// When manually encoding for forms:
function formEncode(str) {
  return encodeURIComponent(str).replace(/%20/g, '+');
}

5. Non-ASCII Characters

// Unicode characters are UTF-8 encoded then percent-encoded
encodeURIComponent("日本語");
// "%E6%97%A5%E6%9C%AC%E8%AA%9E"

encodeURIComponent("é");
// "%C3%A9"

encodeURIComponent("🎉");
// "%F0%9F%8E%89"

Debugging URL Issues

Common Problems

1. Double Encoding

// Already encoded input gets encoded again
const input = "hello%20world"; // Already encoded
encodeURIComponent(input);
// "hello%2520world" - %20 became %2520!

// Fix: Only encode raw strings, or decode first
decodeURIComponent(input); // "hello world"
encodeURIComponent(decodeURIComponent(input)); // "hello%20world"

2. Wrong Function Choice

// Using encodeURI for a parameter value
const search = "price < 100 & discount";
"?q=" + encodeURI(search);
// "?q=price%20%3C%20100%20&%20discount" - & breaks the URL!

// Fix: Use encodeURIComponent for values
"?q=" + encodeURIComponent(search);
// "?q=price%20%3C%20100%20%26%20discount" ✅

3. Encoding the Entire URL

// Wrong: Encoding an already-valid URL
const url = "https://toolsdock.com/path?q=test";
encodeURIComponent(url);
// "https%3A%2F%2Ftoolsdock.com%2Fpath%3Fq%3Dtest" - Broken!

// If you need to pass a URL as a parameter:
const base = "https://redirect.com/?url=";
base + encodeURIComponent(url); // Correct

Debugging Tips

  • Use browser dev tools Network tab to inspect actual URLs sent
  • Decode suspicious URLs with our URL Decoder
  • Check for %25 - it means % was encoded, indicating double encoding
  • Test with characters like & = ? # to verify proper encoding

Tools and Resources

URL Encoder

Encode text for safe URL transmission.

Encode URL
URL Decoder

Decode percent-encoded URLs to readable text.

Decode URL

Quick Reference

Use encodeURIComponent
  • Query parameter values
  • Path segments with special chars
  • URL embedded in another URL
  • Any user input in URLs
Use encodeURI
  • Complete URL with spaces only
  • Rarely needed in practice
  • When URL structure must be preserved

Last updated: December 2024

All URL encoding/decoding on ToolsDock happens in your browser. No data is sent to any server.

Privacy Notice: This site works entirely in your browser. We don't collect or store your data. Optional analytics help us improve the site. You can deny without affecting functionality.