URL Encoder/Decoder Online Free: Complete Guide to Percent-Encoding

DevToolkit Team · · 13 min read

If you've ever pasted a URL into a browser and seen %20 where a space should be, or watched an API call fail because a query parameter contained an ampersand, you've encountered URL encoding. Also known as percent-encoding, it's the mechanism that lets URLs carry special characters safely across the internet.

In this comprehensive guide, we'll cover everything you need to know about URL encoding and decoding: the underlying standard (RFC 3986), how percent-encoding works character by character, the differences between reserved and unreserved characters, practical code examples in JavaScript and Python, a complete reference table of common encodings, and the most frequent mistakes developers make. Whether you need a quick URL encoder decoder online free tool or want to deeply understand the mechanics, this article has you covered.

What Is URL Encoding (Percent-Encoding)?

URL encoding — formally called percent-encoding — is the process of converting characters into a format that can be safely transmitted within a Uniform Resource Locator. URLs are restricted to a specific set of ASCII characters. Any character outside that set, or any reserved character used outside its special purpose, must be encoded.

The encoding is straightforward: each byte of the character's UTF-8 representation is written as a percent sign (%) followed by two hexadecimal digits. For example, a space character (byte value 0x20) becomes %20. A multi-byte character like ü (UTF-8 bytes 0xC3 0xBC) becomes %C3%BC.

This mechanism ensures that every URL remains valid ASCII, even when it references resources with names in Chinese, Arabic, emoji, or any other Unicode script. It's the silent workhorse behind every link you click.

RFC 3986: The Standard Behind URL Encoding

The authoritative specification for URL syntax is RFC 3986 (published in 2005, updating the earlier RFC 2396). It defines the generic syntax for URIs (Uniform Resource Identifiers) and precisely specifies which characters are allowed in each part of a URL without encoding.

RFC 3986 divides characters into two groups:

Unreserved Characters (Never Need Encoding)

These characters can appear anywhere in a URL without being percent-encoded:

A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
a b c d e f g h i j k l m n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
- . _ ~

That's 66 characters total: uppercase letters, lowercase letters, digits, hyphen, period, underscore, and tilde. Everything else either has a special meaning or must be encoded.

Reserved Characters (Special Meaning in URLs)

Reserved characters have specific roles in URL syntax. If you want to use them as literal data (for example, an ampersand in a company name), you must percent-encode them:

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

For example, the ? character separates the path from the query string. If your query value itself contains a question mark, that question mark must be encoded as %3F to avoid ambiguity.

How Percent-Encoding Works Step by Step

Let's walk through encoding the string hello world & goodbye as a URL query parameter value:

  1. Identify characters needing encoding: The space () and ampersand (&) are not unreserved characters, so they must be encoded. The letters are unreserved and stay as-is.
  2. Convert each character to UTF-8 bytes: Space = 0x20, ampersand = 0x26.
  3. Represent each byte as %HH: Space becomes %20, ampersand becomes %26.
  4. Result: hello%20world%20%26%20goodbye

Decoding is the reverse: find every %HH sequence, convert the hex digits back to a byte value, and reconstruct the original character from the UTF-8 bytes. You can try both directions instantly with our free URL encoder decoder tool.

Complete URL Encoding Reference Table

Here are the most commonly encountered percent-encoded characters. Bookmark this table — you'll refer to it more often than you think:

Character   Encoded     Description
─────────   ─────────   ──────────────────────────
(space)     %20         Space character
!           %21         Exclamation mark
"           %22         Double quote
#           %23         Hash / fragment delimiter
$           %24         Dollar sign
%           %25         Percent sign (literal)
&           %26         Ampersand / query separator
'           %27         Single quote / apostrophe
(           %28         Open parenthesis
)           %29         Close parenthesis
*           %2A         Asterisk
+           %2B         Plus sign
,           %2C         Comma
/           %2F         Forward slash / path separator
:           %3A         Colon
;           %3B         Semicolon
=           %3D         Equals sign
?           %3F         Question mark / query delimiter
@           %40         At sign
[           %5B         Open bracket
]           %5D         Close bracket
{           %7B         Open brace
|           %7C         Pipe
{           %7D         Close brace

Notice that the percent sign itself encodes to %25. This is critical: if you double-encode a URL, every % from the first pass gets turned into %25, which is one of the most common bugs in URL handling.

URL Encoding in JavaScript: encodeURIComponent vs encodeURI

JavaScript provides two built-in functions for URL encoding, and using the wrong one is a frequent source of bugs. Understanding the difference is essential for any web developer.

encodeURIComponent()

This function encodes a component of a URI — typically a query parameter key or value. It encodes everything except unreserved characters (A-Z a-z 0-9 - _ . ~):

// Encoding a query parameter value
const searchTerm = "cats & dogs";
const encoded = encodeURIComponent(searchTerm);
console.log(encoded);
// Output: "cats%20%26%20dogs"

// Building a complete query string
const url = "https://example.com/search?q=" + encodeURIComponent(searchTerm);
console.log(url);
// Output: "https://example.com/search?q=cats%20%26%20dogs"

// Encoding special characters
console.log(encodeURIComponent("price=100¤cy=USD"));
// Output: "price%3D100%26currency%3DUSD"

Use encodeURIComponent() when you're encoding a value that will be placed into a URL. This is the function you'll use 90% of the time.

encodeURI()

This function encodes a complete URI. It preserves characters that have structural meaning in a URL (: / ? # [ ] @ ! $ & ' ( ) * + , ; =) and only encodes characters that are invalid in any part of a URL:

// Encoding a complete URL with Unicode characters
const url = "https://example.com/résumé?name=André Müller";
console.log(encodeURI(url));
// Output: "https://example.com/r%C3%A9sum%C3%A9?name=Andr%C3%A9%20M%C3%BCller"

// Notice: the : / ? = are preserved
// Only the accented characters and space are encoded

Use encodeURI() only when you have a complete URL that may contain non-ASCII characters but whose structure (slashes, colons, query delimiters) should remain intact.

Decoding in JavaScript

// decodeURIComponent — decodes a single component
console.log(decodeURIComponent("cats%20%26%20dogs"));
// Output: "cats & dogs"

// decodeURI — decodes a full URI, preserving structural characters
console.log(decodeURI("https://example.com/r%C3%A9sum%C3%A9?q=hello%20world"));
// Output: "https://example.com/résumé?q=hello world"

The Critical Mistake: Using encodeURI on a Parameter Value

// WRONG — encodeURI does NOT encode & and =
const userInput = "tom&jerry=best";
const bad = "https://api.com/search?q=" + encodeURI(userInput);
console.log(bad);
// "https://api.com/search?q=tom&jerry=best"
// The server sees q=tom, jerry=best — completely wrong!

// CORRECT — encodeURIComponent encodes & and =
const good = "https://api.com/search?q=" + encodeURIComponent(userInput);
console.log(good);
// "https://api.com/search?q=tom%26jerry%3Dbest"
// The server correctly sees q=tom&jerry=best

URL Encoding in Python: urllib.parse

Python's standard library provides robust URL encoding and decoding through the urllib.parse module. Here are the key functions:

quote() and quote_plus()

from urllib.parse import quote, quote_plus, urlencode

# quote() — similar to encodeURIComponent
print(quote("hello world & goodbye"))
# Output: "hello%20world%20%26%20goodbye"

# quote_plus() — same but encodes spaces as + instead of %20
# This is the application/x-www-form-urlencoded format
print(quote_plus("hello world & goodbye"))
# Output: "hello+world+%26+goodbye"

# Specifying safe characters (characters NOT to encode)
print(quote("path/to/file", safe="/"))
# Output: "path/to/file"  (slashes preserved)

print(quote("path/to/file", safe=""))
# Output: "path%2Fto%2Ffile"  (slashes encoded)

unquote() and unquote_plus()

from urllib.parse import unquote, unquote_plus

# unquote() — decodes %XX sequences
print(unquote("hello%20world%20%26%20goodbye"))
# Output: "hello world & goodbye"

# unquote_plus() — also converts + back to spaces
print(unquote_plus("hello+world+%26+goodbye"))
# Output: "hello world & goodbye"

urlencode() — Building Query Strings

from urllib.parse import urlencode

# Build a complete query string from a dictionary
params = {
    "q": "cats & dogs",
    "page": 1,
    "lang": "en",
    "filter": "price>=100"
{

query_string = urlencode(params)
print(query_string)
# Output: "q=cats+%26+dogs&page=1&lang=en&filter=price%3E%3D100"

# Use quote_via=quote to get %20 instead of + for spaces
from urllib.parse import quote
query_string = urlencode(params, quote_via=quote)
print(query_string)
# Output: "q=cats%20%26%20dogs&page=1&lang=en&filter=price%3E%3D100"

URL Encoding in Other Languages

PHP

// urlencode() — spaces become +
echo urlencode("hello world & goodbye");
// Output: "hello+world+%26+goodbye"

// rawurlencode() — spaces become %20 (RFC 3986 compliant)
echo rawurlencode("hello world & goodbye");
// Output: "hello%20world%20%26%20goodbye"

// Decoding
echo urldecode("hello+world+%26+goodbye");
// Output: "hello world & goodbye"

Java

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

// Encoding
String encoded = URLEncoder.encode("hello world & goodbye", StandardCharsets.UTF_8);
System.out.println(encoded);
// Output: "hello+world+%26+goodbye"

// Decoding
String decoded = URLDecoder.decode("hello%20world%20%26%20goodbye", StandardCharsets.UTF_8);
System.out.println(decoded);
// Output: "hello world & goodbye"

C# / .NET

using System.Net;
using System;

// Uri.EscapeDataString — RFC 3986 compliant
string encoded = Uri.EscapeDataString("hello world & goodbye");
Console.WriteLine(encoded);
// Output: "hello%20world%20%26%20goodbye"

// WebUtility.UrlEncode — form encoding (+ for spaces)
string formEncoded = WebUtility.UrlEncode("hello world & goodbye");
Console.WriteLine(formEncoded);
// Output: "hello+world+%26+goodbye"

Spaces in URLs: %20 vs + (Plus Sign)

One of the most confusing aspects of URL encoding is the dual representation of spaces. There are two conventions, and mixing them up causes subtle bugs:

In practice, most servers accept both %20 and + in query strings. However, + in a URL path means a literal plus sign, not a space. This distinction has caused countless bugs in web applications.

// These are equivalent in a query string:
https://example.com/search?q=hello+world
https://example.com/search?q=hello%20world

// But in a path, + is literal:
https://example.com/files/C++/readme.txt    // Path contains "C++"
https://example.com/files/C%2B%2B/readme.txt // Same path, percent-encoded

When Should You URL Encode?

Understanding when to encode is just as important as knowing how. Here are the key scenarios:

1. Query Parameter Values

Always encode user-supplied values before inserting them into query strings. This is the single most common use case for URL encoding:

// User types: O'Brien & Sons (price > $100)
const input = "O'Brien & Sons (price > $100)";
const url = `/search?company=${encodeURIComponent(input){`;
// Result: /search?company=O'Brien%20%26%20Sons%20(price%20%3E%20%24100)

2. Path Segments with Special Characters

If a filename or directory name contains reserved characters, encode the individual path segment — not the entire path:

const filename = "report (final).pdf";
const url = `/documents/${encodeURIComponent(filename){`;
// Result: /documents/report%20(final).pdf

3. Non-ASCII Characters (Internationalized URLs)

URLs with characters outside the ASCII range must be encoded. Modern browsers display the decoded version in the address bar for readability, but the actual HTTP request uses the encoded form:

# What you see in the browser:
https://ja.wikipedia.org/wiki/東京

# What's actually sent over HTTP:
https://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC

4. Building API Requests

When constructing API calls programmatically, always encode parameter values. API gateways and servers depend on proper encoding to parse requests correctly:

import requests
from urllib.parse import urlencode, quote

# Using requests library (handles encoding automatically)
response = requests.get("https://api.example.com/search", params={
    "q": "café & restaurant",
    "location": "Zürich"
{)
# Requests builds: /search?q=caf%C3%A9+%26+restaurant&location=Z%C3%BCrich

Common URL Encoding Mistakes (And How to Fix Them)

After years of debugging URL-related issues, these are the most frequent problems developers encounter. Avoid these pitfalls to save yourself hours of frustration.

Mistake 1: Double Encoding

This is the number one URL encoding bug. It happens when you encode a string that's already been encoded, turning %20 into %2520:

// The bug
const alreadyEncoded = "hello%20world";
const doubleEncoded = encodeURIComponent(alreadyEncoded);
console.log(doubleEncoded);
// "hello%2520world" — BROKEN! %25 is the encoding of %

// The fix: only encode raw values, never encoded strings
// If you're unsure whether a string is already encoded,
// decode first, then re-encode:
const safeEncode = (str) => {
  try {
    return encodeURIComponent(decodeURIComponent(str));
  { catch (e) {
    return encodeURIComponent(str);
  {
{;

Mistake 2: Not Encoding Query Parameter Values

String concatenation without encoding is dangerously common and can break functionality or create security vulnerabilities:

// WRONG — if userInput contains & or =, the URL breaks
const url = `https://api.com/data?name=${userInput{`;

// CORRECT — always encode
const url = `https://api.com/data?name=${encodeURIComponent(userInput){`;

Mistake 3: Encoding the Entire URL

Encoding a complete URL with encodeURIComponent() destroys its structure:

// WRONG
const broken = encodeURIComponent("https://example.com/path?key=value");
// "https%3A%2F%2Fexample.com%2Fpath%3Fkey%3Dvalue" — not a valid URL!

// CORRECT — encode only the parts that need it
const url = "https://example.com/path?key=" + encodeURIComponent(userValue);

Mistake 4: Forgetting to Decode on the Server

If your server receives caf%C3%A9 and stores it without decoding, you end up with literal percent signs in your database. Most web frameworks handle this automatically, but raw HTTP parsing or custom routing may not.

Mistake 5: Mixing + and %20 Incorrectly

Using + for spaces in URL paths (where it means a literal plus sign) or using %20 in form-encoded bodies (where the convention expects +) causes mismatches between what you send and what the server interprets.

Debugging Encoded URLs

When something goes wrong with a URL, here's a systematic approach to debugging:

  1. Decode the URL using our URL encoder decoder online free tool to see the plain-text version. Visually inspect whether it matches what you expect.
  2. Check for double encoding: Look for %25 sequences. If you see %2520, %253A, or similar, the URL was encoded twice.
  3. Inspect the raw HTTP request: Use browser DevTools (Network tab) or a proxy like Charles/Fiddler to see exactly what bytes were sent. The browser's address bar may show a decoded version for readability.
  4. Verify each component separately: Break the URL into scheme, host, path, query key-value pairs, and fragment. Check that encoding was applied at the right level.
  5. Test with known values: Send a request with a known special character (like &) in a parameter and verify the server receives it correctly.

For quickly decoding and re-encoding URLs during debugging, use our free online URL encoder/decoder. You might also find our JSON formatter helpful when inspecting API response bodies that contain encoded URLs, or our Base64 encoder when dealing with Base64-encoded URL parameters.

Query String Encoding in Detail

Query strings follow the format ?key1=value1&key2=value2. Properly encoding them requires attention to several details:

// Building query strings correctly in JavaScript
function buildQueryString(params) {
  return Object.entries(params)
    .map(([key, value]) =>
      `${encodeURIComponent(key){=${encodeURIComponent(value){`
    )
    .join('&');
{

const params = {
  search: "cats & dogs",
  page: "2",
  filter: "price>=10",
  tag: "cute/funny"
{;

console.log(buildQueryString(params));
// search=cats%20%26%20dogs&page=2&filter=price%3E%3D10&tag=cute%2Ffunny

Modern JavaScript also provides the URLSearchParams API, which handles encoding automatically:

const params = new URLSearchParams({
  search: "cats & dogs",
  filter: "price>=10"
{);

console.log(params.toString());
// "search=cats+%26+dogs&filter=price%3E%3D10"
// Note: URLSearchParams uses + for spaces (form encoding convention)

// Building a complete URL
const url = new URL("https://example.com/search");
url.searchParams.set("q", "hello world & goodbye");
console.log(url.toString());
// "https://example.com/search?q=hello+world+%26+goodbye"

URL Encoding and Security

URL encoding intersects with security in several important ways:

URL Encoding for International Domain Names (IDN)

While the path and query parts of a URL use percent-encoding for non-ASCII characters, domain names use a different system called Punycode (RFC 3492). For example:

// Human-readable:
https://münchen.de/straße?q=grüße

// Actual URL sent over HTTP:
// Domain uses Punycode: münchen.de → xn--mnchen-3ya.de
// Path uses percent-encoding: straße → stra%C3%9Fe
// Query uses percent-encoding: grüße → gr%C3%BC%C3%9Fe
https://xn--mnchen-3ya.de/stra%C3%9Fe?q=gr%C3%BC%C3%9Fe

This is handled automatically by browsers and HTTP libraries, but it's important to understand when debugging internationalized URLs.

URL Length Limits and Encoding Overhead

Percent-encoding increases URL length: each encoded character becomes three characters (%XX), and multi-byte UTF-8 characters can expand even more. A single emoji like a thumbs-up sign is 4 UTF-8 bytes, which becomes 12 characters when percent-encoded (%F0%9F%91%8D).

While RFC 3986 doesn't define a maximum URL length, practical limits exist:

If your encoded URL is too long, consider sending the data in a POST request body instead, or use shortened identifiers that the server can look up.

URL Encoding vs Other Encoding Schemes

URL encoding is one of several encoding systems developers encounter. Here's how they compare:

It's common to combine these: a JSON payload might be Base64-encoded and then URL-encoded to pass through a query string. Just be careful about the order of encoding and decoding.

Quick Reference: URL Encoding Cheat Sheet

Here's a concise reference for the most common URL encoding scenarios:

Scenario                        JavaScript                     Python
──────────────────────────────  ─────────────────────────────  ──────────────────────────
Encode a query value            encodeURIComponent(val)        quote(val)
Encode a full URL               encodeURI(url)                 quote(url, safe=':/?#[]@!$&\'()*+,;=')
Encode spaces as +              N/A (use URLSearchParams)      quote_plus(val)
Build query string from dict    new URLSearchParams(obj)       urlencode(dict)
Decode a component              decodeURIComponent(val)        unquote(val)
Decode + as space               decodeURIComponent(            unquote_plus(val)
                                  val.replace(/\+/g, ' '))
Decode a full URL               decodeURI(url)                 unquote(url)

Wrapping Up

URL encoding is a foundational web skill that sits at the intersection of standards compliance, security, and practical debugging. Whether you're building API integrations, handling form submissions, working with international content, or just trying to figure out why your query parameter is breaking, understanding percent-encoding will save you time and frustration.

The key takeaways:

Ready to encode or decode a URL right now? Head over to our free URL encoder decoder online tool — paste your string, get instant results, no sign-up required.

Enjoyed this article?

Get the free Developer Cheatsheet Pack + weekly tips on tools, workflows, and productivity.

Subscribe Free

Try These Tools

Related free tools mentioned in this article

Back to Blog