What is URL encoding?

URL encoding (also called percent-encoding) converts characters that are not allowed or have special meaning in URLs into a safe format. Each unsafe character is replaced with a % sign followed by two hexadecimal digits representing the character's UTF-8 byte value. The specification is defined in RFC 3986.

In JavaScript, encodeURIComponent() encodes a value for use as a query string parameter or path segment, escaping everything except letters, digits, and - _ . ! ~ * ' ( ). Use encodeURI() only for full URLs where you want to preserve the structure (slashes, colons, question marks).

For example, a space becomes %20, a question mark becomes %3F, and an ampersand becomes %26. Letters, digits, and - _ . ~ are always safe and never encoded.

How to encode and decode URLs

  1. 1
    Choose Encode or Decode

    Select Encode to make text URL-safe. Select Decode to convert percent-encoded strings back to readable text.

  2. 2
    Paste your input

    Enter the URL, query string, or text you want to convert. The tool handles the full UTF-8 range including Unicode characters and emoji.

  3. 3
    Use Swap for roundtrip testing

    Click Swap to switch modes and move the output to the input. Useful for verifying that encode → decode returns the original string.

  4. 4
    Copy and use

    Copy the encoded or decoded result directly into your code, API request, or browser address bar.

Common percent-encoded characters

CharacterEncodedNotes
Space%20Use %20 in paths. In form data (application/x-www-form-urlencoded), spaces may be encoded as + instead.
# (hash)%23Indicates a fragment identifier in URLs — must be encoded in query values.
& (ampersand)%26Separates query parameters — must be encoded within parameter values.
= (equals)%3DSeparates key from value in query strings — must be encoded in values.
? (question)%3FStarts the query string — must be encoded in path segments.
+ (plus)%2BCan be interpreted as a space in form data — encode explicitly to avoid ambiguity.
@ (at)%40Commonly used in email addresses within URLs.
/ (slash)%2FPath separator — encode when it appears within a segment, not as a separator.

URL structure anatomy

A URL (Uniform Resource Locator) has a well-defined structure defined by RFC 3986. Understanding each component clarifies which characters must be encoded and where:

ComponentExampleWhen to encode
Schemehttps://Never — use as-is
Hostexample.comPunycode for non-ASCII domains (e.g. münchen.de → xn--mnchen-3ya.de)
Port:8080Never — numeric only
Path/search/resultsEncode reserved characters within segments; / separators must remain unencoded
Query key?q=Encode with encodeURIComponent() — keys can contain any character
Query value?q=hello+worldEncode with encodeURIComponent() — most important part to encode
Fragment#section-1Encode if it contains non-ASCII or reserved characters

encodeURI vs encodeURIComponent — which to use

JavaScript provides two built-in encoding functions, and choosing the wrong one is one of the most common URL-related bugs in web development.

encodeURIComponent()

Use for: Encoding a query parameter value, a path segment, or any user-supplied string that will be embedded inside a URL.

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

Encodes: Everything else, including / : ? & = # @ (all URL structure characters)

Tip: Use this by default. It is the safer of the two because it encodes all URL structure characters that could be misinterpreted.

encodeURI()

Use for: Encoding a complete URL that you want to preserve as a URL (keep the slashes and question marks intact).

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

Encodes: Only characters not allowed anywhere in a URL (e.g. spaces → %20, curly braces, pipe, backslash)

Tip: Use only when encoding a full URL, not a value within a URL.

Common developer use cases

Building API query strings
Encode user search input before appending to an API URL: fetch(`/api?q=${encodeURIComponent(userInput)}`).
Redirect URLs in OAuth
OAuth redirect_uri parameters must be URL-encoded before being passed as a query parameter: ?redirect_uri=https%3A%2F%2F...
Sharing URLs in emails
URLs pasted into email bodies often get mangled. Encoding special characters ensures the link survives email client handling.
Embedding URLs in HTML attributes
Encoding prevents HTML attribute injection. Encode values that appear inside href, src, and action attributes when they come from user input.
Decoding API responses
Some APIs return percent-encoded strings (especially in Location headers and link previews). Decode them to get the human-readable URL.
URL parameters in single-page apps
React Router and other SPA frameworks use encoded URLs to store state. Decoding route params before use prevents rendering bugs with special characters in IDs.

URL encoding across programming languages

Every language has built-in URL encoding utilities. Here are the canonical functions to use — and the ones to avoid:

JavaScript / TypeScript
Encode: encodeURIComponent(value)
Decode: decodeURIComponent(encoded)
Avoid: escape() — deprecated, broken for Unicode
Python 3
Encode: urllib.parse.quote(value, safe="")
Decode: urllib.parse.unquote(encoded)
Avoid: urllib.quote() — removed in Python 3
Node.js
Encode: encodeURIComponent() or new URLSearchParams()
Decode: decodeURIComponent()
Avoid: querystring — deprecated since Node 14
PHP
Encode: rawurlencode($value)
Decode: rawurldecode($encoded)
Avoid: urlencode() — encodes spaces as + not %20
Go
Encode: url.QueryEscape(value)
Decode: url.QueryUnescape(encoded)
Avoid: Manual string replacement
Java
Encode: URLEncoder.encode(value, StandardCharsets.UTF_8)
Decode: URLDecoder.decode(encoded, StandardCharsets.UTF_8)
Avoid: URLEncoder.encode(value) without charset arg
Ruby
Encode: URI.encode_www_form_component(value)
Decode: URI.decode_www_form_component(encoded)
Avoid: CGI.escape() — spaces become +
C# / .NET
Encode: Uri.EscapeDataString(value)
Decode: Uri.UnescapeDataString(encoded)
Avoid: HttpUtility.UrlEncode() — encodes spaces as +

Debugging common URL encoding mistakes

Spaces encoded as + instead of %20
Cause: application/x-www-form-urlencoded (HTML form POST) encodes spaces as +. This is correct for form bodies but wrong for URL paths and REST API query strings.
Fix: Use encodeURIComponent() — it always produces %20. When decoding a + as a space: decodeURIComponent(str.replace(/\+/g, " ")).
Double-encoding: %2520 instead of %20
Cause: The URL was encoded twice. The % in %20 was then encoded to %25, producing %2520. Happens when encoding an already-encoded string.
Fix: Always encode raw values, never pre-encoded strings. If in doubt, decode first then re-encode.
Non-ASCII characters not encoded
Cause: Older functions like JavaScript's escape() or Python 2's urllib.quote() do not handle multi-byte UTF-8 correctly.
Fix: Use encodeURIComponent() in JS and urllib.parse.quote(value, safe="", encoding="utf-8") in Python.
Slashes in path values not encoded
Cause: A value like /uploads/user/file.jpg passed as a query parameter must have its slashes encoded as %2F. Leaving them unencoded breaks the URL parser.
Fix: Always use encodeURIComponent() (not encodeURI()) for individual values. encodeURI() intentionally skips encoding slashes.

FAQ

Common questions

What is URL encoding?

URL encoding (percent-encoding) converts characters that are not allowed in URLs into a safe format. Special characters are replaced with a % followed by two hex digits. For example, a space becomes %20.

Which characters need encoding?

Reserved characters like ?, &, =, #, /, +, and non-ASCII characters (like accented letters or emoji) must be encoded. Letters, digits, and - _ . ~ are safe without encoding.

What is the difference between encodeURI and encodeURIComponent?

encodeURI encodes a full URL, leaving structural characters like /, ?, # intact. encodeURIComponent encodes everything including those characters — use it for individual query parameter values.

Why does my URL have %20 instead of +?

%20 is the correct percent-encoding for a space in any URL context. The + sign is a legacy encoding for spaces in HTML form submissions (application/x-www-form-urlencoded) only.

When should I decode a URL?

Decode URLs when displaying them to users (readable addresses look cleaner), when parsing query parameter values in server-side code, or when debugging API requests. Never decode a URL before passing it to a fetch() or HTTP client — always keep the encoded form during transmission so reserved characters retain their structural meaning.

What is double encoding and why is it a problem?

Double encoding happens when you encode an already-encoded URL. The % in %20 itself gets encoded to %2520, so a space becomes %2520 instead of %20. This usually happens when encoding is applied twice — for example, encoding a value before inserting it into a string that gets encoded again. Always encode raw values, not already-encoded strings.

Which characters are always safe in URLs without encoding?

The unreserved characters defined in RFC 3986 are always safe: A–Z, a–z, 0–9, hyphen (-), underscore (_), period (.), and tilde (~). Everything else — including spaces, non-ASCII characters, and most punctuation — should be percent-encoded. Encoding the unreserved characters is technically valid but unnecessary and produces longer URLs.

How do I encode a URL in JavaScript?

Use encodeURIComponent() for individual values: encodeURIComponent("hello world") → "hello%20world". Use encodeURI() for a complete URL when you want to preserve the URL structure (slashes, colons, question marks remain unencoded). To decode, use decodeURIComponent() or decodeURI() respectively. Never use the deprecated escape() function.

More in Developer Tools