URL Encode & Decode

Percent-encode text for query strings and paths, or decode URL-encoded values back to text

Conversion direction

Encode a single value (query parameter or path segment), not the whole URL.

What is URL Encoding (Percent-Encoding)?

URL encoding, formally known as percent-encoding, is the mechanism defined by RFC 3986 for representing arbitrary data within the components of a Uniform Resource Identifier. Characters that are not allowed in a URI β€” or that carry special syntactic meaning β€” are replaced with one or more triplets of the form %HH, where HH is the two-digit uppercase hexadecimal value of the byte. For example, a space character (byte 0x20) becomes %20, and the at-sign @ (byte 0x40) becomes %40. This encoding ensures that URIs remain unambiguous across all transport layers, file systems, and character sets while preserving the structural delimiters that separate scheme, authority, path, query, and fragment components.

Percent-Encoding Rules: How It Works

RFC 3986 Β§2.1 defines the percent-encoding mechanism: each octet that requires encoding is represented as a percent sign followed by two hexadecimal digits. The encoding operates on raw bytes, not characters, which means multi-byte UTF-8 characters produce multiple percent-encoded triplets. The character "Γ©" (U+00E9) encodes to %C3%A9 because its UTF-8 representation is two bytes: 0xC3 and 0xA9.

The specification distinguishes between three categories of characters:

  • Unreserved characters (never encode): A-Z a-z 0-9 - _ . ~ β€” these 66 characters are always safe in any URI component and MUST NOT be percent-encoded.
  • Reserved characters (encode when not used as delimiters): : / ? # [ ] @ ! $ & ' ( ) * + , ; = β€” these have defined syntactic roles. Encode them only when they appear as data within a component, not when they serve as delimiters.
  • All other characters (always encode): spaces, non-ASCII bytes, control characters, and characters not in the unreserved or reserved sets must always be percent-encoded.

A critical principle is that encoding is context-dependent. The slash / must be encoded inside a query parameter value (%2F) but must NOT be encoded when it separates path segments. Similarly, = and & must be encoded inside parameter values but serve as delimiters in the query string structure itself.

Reserved Characters Reference Table

The following table lists all reserved characters defined in RFC 3986 Β§2.2, their percent-encoded form, and their syntactic role within URIs:

  • : β†’ %3A β€” separates scheme from authority, port from host
  • / β†’ %2F β€” separates path segments
  • ? β†’ %3F β€” begins query component
  • # β†’ %23 β€” begins fragment identifier
  • [ β†’ %5B β€” IPv6 address in authority
  • ] β†’ %5D β€” IPv6 address in authority
  • @ β†’ %40 β€” separates userinfo from host
  • ! β†’ %21 β€” sub-delimiter
  • $ β†’ %24 β€” sub-delimiter
  • & β†’ %26 β€” separates query parameters
  • ' β†’ %27 β€” sub-delimiter
  • ( β†’ %28 β€” sub-delimiter
  • ) β†’ %29 β€” sub-delimiter
  • * β†’ %2A β€” sub-delimiter
  • + β†’ %2B β€” sub-delimiter (also space in form encoding)
  • , β†’ %2C β€” sub-delimiter
  • ; β†’ %3B β€” sub-delimiter
  • = β†’ %3D β€” separates key from value in query parameters

encodeURIComponent vs encodeURI: Choosing the Right Function

JavaScript provides two built-in functions for URL encoding, and using the wrong one is a frequent source of bugs:

  • encodeURIComponent() encodes everything except unreserved characters (A-Z a-z 0-9 - _ . ~ ! ' ( ) *). Use this for encoding individual URI components such as query parameter values, path segments, or fragment identifiers. It encodes / ? # @ & = + , and all other reserved characters.
  • encodeURI() preserves the structural characters that form a complete URI: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. Use this only when you have a full URI string and want to encode illegal characters (spaces, non-ASCII) without breaking the URI structure.

The practical rule: when building query strings or encoding user input to embed in a URL, always use encodeURIComponent(). Using encodeURI() for parameter values leaves dangerous characters like & and = unencoded, which corrupts the query string structure and can introduce security vulnerabilities (parameter injection).

This tool uses encodeURIComponent() by default because it covers the most common use case: encoding a value that will be embedded inside a URI component. It ensures that reserved characters within the data do not accidentally act as structural delimiters.

Form Encoding: application/x-www-form-urlencoded

HTML forms submitted with method="POST" and the default content type use a variant of percent-encoding defined in the WHATWG URL Standard. This format β€” application/x-www-form-urlencoded β€” differs from RFC 3986 in one key way: spaces are encoded as + instead of %20. All other special characters follow standard percent-encoding rules.

When constructing form data programmatically in JavaScript, use the URLSearchParams API rather than manual string concatenation. It handles the space-to-plus conversion, proper encoding of all special characters, and correct key=value&key=value formatting automatically:

Be aware that encodeURIComponent() encodes spaces as %20, not +. If you need form-encoded output (for POST bodies or legacy systems expecting + for spaces), apply encodeURIComponent() first, then replace %20 with +, or use URLSearchParams which handles this automatically.

When to Encode: Practical Scenarios

URL encoding is required in several common development workflows:

  • Query string parameters: User input placed into URLs must be encoded. A search query like "price > 100 & color = blue" must become price%20%3E%20100%20%26%20color%20%3D%20blue to avoid corrupting the URL structure.
  • Path segments with special characters: File names or resource identifiers containing spaces, slashes, or Unicode characters need encoding before being placed in URL paths.
  • OAuth and API signatures: OAuth 1.0 requires RFC 3986 percent-encoding of all signature base string components. Incorrect encoding produces invalid signatures.
  • Redirect URLs: When passing a URL as a parameter value (e.g., ?redirect=https://...), the inner URL's colons, slashes, and query characters must be encoded.
  • Cookie values: While not strictly required by the RFC, encoding cookie values prevents issues with semicolons, commas, and whitespace that have special meaning in the Cookie header.

Code Examples

URL encoding in JavaScript: encodeURIComponent vs encodeURI

// Encoding a query parameter value (CORRECT)
const userQuery = 'price > 100 & color = blue';
const safeParam = encodeURIComponent(userQuery);
// β†’ "price%20%3E%20100%20%26%20color%20%3D%20blue"

const url = `https://api.example.com/search?q=${safeParam}`;
// β†’ "https://api.example.com/search?q=price%20%3E%20100%20%26%20color%20%3D%20blue"

// Building query strings with URLSearchParams (handles form encoding)
const params = new URLSearchParams({
  name: 'JosΓ© GarcΓ­a',
  query: 'a=1&b=2',
  path: '/users/admin'
});
console.log(params.toString());
// β†’ "name=Jos%C3%A9+Garc%C3%ADa&query=a%3D1%26b%3D2&path=%2Fusers%2Fadmin"

// encodeURI preserves URI structure (use for full URLs only)
const fullUrl = 'https://example.com/path with spaces/file.html';
console.log(encodeURI(fullUrl));
// β†’ "https://example.com/path%20with%20spaces/file.html"

Encoding non-ASCII characters (UTF-8 percent-encoding)

// Multi-byte UTF-8 characters produce multiple %HH triplets
console.log(encodeURIComponent('cafΓ©'));
// β†’ "caf%C3%A9" (Γ© = 2 UTF-8 bytes: 0xC3, 0xA9)

console.log(encodeURIComponent('ζ—₯本θͺž'));
// β†’ "%E6%97%A5%E6%9C%AC%E8%AA%9E" (3 bytes per character)

console.log(encodeURIComponent('πŸš€'));
// β†’ "%F0%9F%9A%80" (4 UTF-8 bytes for emoji)

Standards & Specifications

  • RFC 3986 β€” Uniform Resource Identifier (URI): Generic Syntax β€” defines percent-encoding, reserved/unreserved character sets, and URI component structure
  • WHATWG URL Standard β€” Defines application/x-www-form-urlencoded encoding used by HTML forms (space as +, different encoding set)

Frequently Asked Questions

Why do I need URL encoding?

Only a limited set of characters is allowed in a URL. Percent-encoding turns spaces, accents and reserved characters such as & = ? # into %XX sequences so a value cannot break the URL structure.

Should I encode the entire URL?

No. Encode individual values (a query parameter value or a path segment). Encoding the whole URL would also escape the :// , ? and & that give the URL its structure.

When do I need URL decoding?

When you need to read values copied from query strings, server logs or redirect parameters, for example turning q%3Dcaf%C3%A9 back into q=cafΓ©.

Why am I getting a decoding error?

The input contains a % that is not followed by two hexadecimal digits, or a byte sequence that is not valid UTF-8. This usually means the text was truncated or only partly encoded.

What's the difference between URL encoding and Base64?

URL encoding only escapes characters that are unsafe in URLs and leaves the rest readable. Base64 re-encodes every byte into a 64-character alphabet and is meant for binary data.

Is my data sent to a server?

No. Encoding and decoding run in your browser; nothing you paste is uploaded.