Developer tools

How to Decode a URL Encoded String (%20 and More Explained)

Decode URL encoded strings like %20 and %3A online or in JavaScript, Python, Java and C#. Learn encodeURIComponent, + vs %20 and query strings.

· 4 min read

To decode a URL encoded string, paste it into our URL encode/decode tool and choose Decode. Sequences like %20, %3A and %2F turn back into a space, : and /, and non-English text such as %E0%A4%A8 turns back into the original letters. To go the other way, choose Encode to make text safe for a URL or query string. It all runs in your browser.

Here is what those percent signs mean, and how to encode and decode URLs in JavaScript, Python, Java and C#.

What URL encoding is

URLs can only contain a limited set of characters: letters, digits and a few symbols like -, _, . and ~. Some other characters have special jobs:

Character Job in a URL
/ Separates path segments
? Starts the query string
& Separates query parameters
= Separates a parameter name from its value
# Starts the fragment (a position in the page)
+ Means a space in form-encoded query strings
% Starts an encoded character

To include any other character, or to use one of these as ordinary data, it is percent-encoded: replaced by % followed by its byte value in hexadecimal. This is also called URL encoding.

Common encoded characters

Character Encoded
Space %20 (or + in form data)
! %21
" %22
# %23
% %25
& %26
+ %2B
/ %2F
: %3A
= %3D
? %3F
@ %40

Non-English characters are first converted to UTF-8 bytes, and each byte is encoded. The Hindi letter न is three bytes in UTF-8, so it becomes %E0%A4%A8. That is why a Hindi or emoji URL looks so long when you copy it.

%20 vs +

Both can mean a space, but not everywhere:

  • %20 is a space anywhere in a URL.
  • + is a space only in query strings encoded the way HTML forms do it (application/x-www-form-urlencoded). In a path, + is a literal plus.

Our decoder treats + as a space, which is what you want for query strings and form data. If you are decoding a path that contains a real plus sign, check the result.

Why query strings need encoding

Say you want to pass the value Tom & Jerry as a search parameter:

https://example.com/search?q=Tom & Jerry

The & would be read as the start of a new parameter, and the space breaks the URL. Encoded properly:

https://example.com/search?q=Tom%20%26%20Jerry

The same applies to email addresses, other URLs passed as parameters (like a redirect= value), and anything containing =, ? or #.

encodeURIComponent vs encodeURI (JavaScript)

Function Leaves alone Use for
encodeURI() A–Z a–z 0–9 - _ . ! ~ * ' ( ) ; / ? : @ & = + $ , # A complete URL you just want to make valid
encodeURIComponent() A–Z a–z 0–9 - _ . ! ~ * ' ( ) A single value going into a query string or path segment

Example:

  • encodeURIComponent('a&b=c') gives a%26b%3Dc
  • encodeURI('a&b=c') gives a&b=c (unchanged)

Our tool uses encodeURIComponent, which is the right choice for individual query parameter values. To decode, JavaScript has decodeURIComponent() and decodeURI(). decodeURIComponent throws a "URIError: URI malformed" if it meets a broken sequence like %E0%A4 (incomplete) or a lone %.

For building query strings, URLSearchParams handles encoding for you:

new URLSearchParams({ q: 'Tom & Jerry', page: 2 }).toString() gives q=Tom+%26+Jerry&page=2.

How to decode a URL encoded string in Python

from urllib.parse import quote, unquote, quote_plus, unquote_plus, urlencode
unquote('hello%20world')          # 'hello world'
unquote_plus('hello+world')       # 'hello world'
quote('a&b=c', safe='')           # 'a%26b%3Dc'
urlencode({'q': 'Tom & Jerry'})   # 'q=Tom+%26+Jerry'

By default quote leaves / unencoded; pass safe='' to encode it too.

In Java and C#

  • Java: URLDecoder.decode(s, StandardCharsets.UTF_8) and URLEncoder.encode(s, StandardCharsets.UTF_8) (Java 10+; older versions take "UTF-8" as a string). These use form encoding, so spaces become +.
  • C#: Uri.UnescapeDataString(s) decodes; Uri.EscapeDataString(s) encodes using %20 for spaces. WebUtility.UrlDecode and WebUtility.UrlEncode use + for spaces.

Double encoding

If you see %2520 in a URL, the text was encoded twice: %20 was encoded again, and the % became %25. Decode once and you get %20; decode again to get the space. This usually happens when a value is encoded by your code and then again by a library. Encode exactly once, at the point where the value goes into the URL.

URL encoding vs Base64

URL encoding makes text safe for URLs while keeping it mostly readable. Base64 turns any data, including binary, into a compact text form, but it is unreadable and is not URL-safe by default. If you need to put a Base64 string in a URL, use the URL-safe variant or percent-encode its +, / and =. See Base64 encode/decode and our guide on decoding Base64.

If the decoded value is a block of JSON, as often happens with tracking links and API callbacks, paste it into the JSON formatter to read it.

Common mistakes

  • Building URLs by gluing strings together without encoding values, which breaks as soon as a value contains & or a space.
  • Using encodeURI for a parameter value, leaving & and = unencoded.
  • Encoding twice, producing %2520.
  • Treating + as a space in a URL path. It only means a space in form-encoded query strings.
  • Putting personal data in URLs. Even encoded, it is readable and ends up in browser history and server logs.

Questions

What does %20 mean in a URL?

%20 is a space. URLs cannot contain spaces, so each one is replaced by a percent sign followed by its character code in hexadecimal, which for a space is 20.

What is the difference between %20 and + in a URL?

Both can represent a space. %20 works anywhere in a URL. + means a space only in query strings sent by HTML forms; in the path part of a URL, + is a literal plus sign.

What is the difference between encodeURI and encodeURIComponent?

encodeURI encodes a full URL but leaves characters like / ? & = # alone so the URL still works. encodeURIComponent encodes those too, which makes it right for a single query parameter value.

How do I decode a URL in Python?

Use urllib.parse.unquote('hello%20world') to get 'hello world'. For form data where + means space, use urllib.parse.unquote_plus.

Related guides

All guides