URL Decoder
Decode URLs, parse query parameters, strip tracking codes
Paste any percent-encoded URL or value and get it back in plain text. Full URLs are broken into a structured view with a per-parameter table so you can spot and remove tracking codes (utm_*, fbclid, gclid, msclkid, mc_*) in one click. Includes a complete %XX reference with per-character explanations, a multi-byte UTF-8 lookup, and a batch mode.
Encoded input
Decoded outputdecodeURIComponent
Decoded output will appear here.
Related web tools
Look up a percent-encoded character
Type any %XX code (or a multi-byte sequence like %E2%9C%93) to see what character it represents.
Spaces are not allowed in URLs and must always be percent-encoded. In application/x-www-form-urlencoded bodies (HTML form posts), spaces are encoded as `+` instead.
Percent-Encoding Reference
Every common %XX code with the character it represents, its Unicode code point, and when it appears. Click a row to jump to a longer explanation.
| Code | Character | Name | Unicode | Type |
|---|---|---|---|---|
| %20 | · (space) | Space | U+0020 | encoded |
| %21 | ! | Exclamation mark | U+0021 | reserved |
| %22 | " | Double quote | U+0022 | encoded |
| %23 | # | Hash / number sign | U+0023 | reserved |
| %24 | $ | Dollar sign | U+0024 | reserved |
| %25 | % | Percent sign | U+0025 | encoded |
| %26 | & | Ampersand | U+0026 | reserved |
| %27 | ' | Apostrophe | U+0027 | reserved |
| %28 | ( | Left parenthesis | U+0028 | reserved |
| %29 | ) | Right parenthesis | U+0029 | reserved |
| %2A | * | Asterisk | U+002A | reserved |
| %2B | + | Plus sign | U+002B | reserved |
| %2C | , | Comma | U+002C | reserved |
| %2F | / | Forward slash | U+002F | reserved |
| %3A | : | Colon | U+003A | reserved |
| %3B | ; | Semicolon | U+003B | reserved |
| %3C | < | Less-than sign | U+003C | encoded |
| %3D | = | Equals sign | U+003D | reserved |
| %3E | > | Greater-than sign | U+003E | encoded |
| %3F | ? | Question mark | U+003F | reserved |
| %40 | @ | At sign | U+0040 | reserved |
| %5B | [ | Left square bracket | U+005B | reserved |
| %5C | \ | Backslash | U+005C | encoded |
| %5D | ] | Right square bracket | U+005D | reserved |
| %5E | ^ | Caret | U+005E | encoded |
| %60 | ` | Backtick | U+0060 | encoded |
| %7B | { | Left curly brace | U+007B | encoded |
| %7C | | | Pipe | U+007C | encoded |
| %7D | } | Right curly brace | U+007D | encoded |
| %7E | ~ | Tilde | U+007E | encoded |
| %0A | ↵ (LF) | Line feed (LF) | U+000A | encoded |
| %0D | ↵ (CR) | Carriage return (CR) | U+000D | encoded |
| %09 | → (tab) | Tab | U+0009 | encoded |
Reserved characters have special meaning in URL syntax (separators, delimiters). Encodedcharacters aren't allowed as literals and must always be percent-encoded. Characters not on this list (letters, digits, - . _ ~) are unreserved and should never be encoded.
What does each %XX mean? (long-form explanations)
One short section per character — most useful when you're debugging an unfamiliar URL and want to know whether a particular code is doing something special.
%20 decoded — Space (U+0020)
Decodes to: · (space)
Spaces are not allowed in URLs and must always be percent-encoded. In application/x-www-form-urlencoded bodies (HTML form posts), spaces are encoded as `+` instead.
%21 decoded — Exclamation mark (U+0021)
Decodes to: !
Reserved sub-delim. Modern encoders leave it unencoded in path components.
%22 decoded — Double quote (U+0022)
Decodes to: "
Always encoded — invalid as a literal character in URLs.
%23 decoded — Hash / number sign (U+0023)
Decodes to: #
Reserved as the fragment separator (everything after `#` is the fragment). Must be encoded inside path or query values.
%24 decoded — Dollar sign (U+0024)
Decodes to: $
Reserved sub-delim — usually left unencoded in path components.
%25 decoded — Percent sign (U+0025)
Decodes to: %
A literal `%` must be encoded as `%25` — otherwise it starts a percent-encoded sequence and decoders will throw.
%26 decoded — Ampersand (U+0026)
Decodes to: &
Separator between query parameters. Must be encoded inside a parameter value or it breaks parsing.
%27 decoded — Apostrophe (U+0027)
Decodes to: '
Sub-delim. Often encoded by encoders even when allowed, to be safe.
%28 decoded — Left parenthesis (U+0028)
Decodes to: (
Sub-delim. Usually left unencoded in modern URLs.
%29 decoded — Right parenthesis (U+0029)
Decodes to: )
Sub-delim. Usually left unencoded in modern URLs.
%2A decoded — Asterisk (U+002A)
Decodes to: *
Sub-delim. Often encoded in older systems; modern URLs typically leave it as-is.
%2B decoded — Plus sign (U+002B)
Decodes to: +
Special case: in standard URLs `+` is a literal `+`. In `application/x-www-form-urlencoded` data (HTML form submissions and query strings posted by forms), `+` is a SPACE — many bugs live here.
%2C decoded — Comma (U+002C)
Decodes to: ,
Sub-delim. Common in faceted-navigation URLs as a value separator (e.g. `colors=red,blue`).
%2F decoded — Forward slash (U+002F)
Decodes to: /
Path separator. Must be encoded inside a path segment or query value to avoid being interpreted as a new path level.
%3A decoded — Colon (U+003A)
Decodes to: :
Reserved separator (between scheme/host, between host/port, between user/password in userinfo).
%3B decoded — Semicolon (U+003B)
Decodes to: ;
Sub-delim. Historically used as a path-parameter separator (rare today).
%3C decoded — Less-than sign (U+003C)
Decodes to: <
Always encoded — security-sensitive (used in XSS attacks if leaked into HTML).
%3D decoded — Equals sign (U+003D)
Decodes to: =
Separator between query parameter name and value. Must be encoded inside a value.
%3E decoded — Greater-than sign (U+003E)
Decodes to: >
Always encoded — security-sensitive (used in XSS attacks if leaked into HTML).
%3F decoded — Question mark (U+003F)
Decodes to: ?
Reserved — marks the start of the query string. Must be encoded inside a path or value.
%40 decoded — At sign (U+0040)
Decodes to: @
Reserved — separates userinfo from the host in `user@host`. Common in encoded email addresses.
%5B decoded — Left square bracket (U+005B)
Decodes to: [
Reserved — wraps IPv6 literal addresses in URLs (e.g. `http://[::1]/`).
%5C decoded — Backslash (U+005C)
Decodes to: \
Not valid in URLs and must be encoded. Browsers often silently convert to `/`.
%5D decoded — Right square bracket (U+005D)
Decodes to: ]
Reserved — closes IPv6 literal addresses.
%5E decoded — Caret (U+005E)
Decodes to: ^
Always encoded — not in the URL unreserved set.
%60 decoded — Backtick (U+0060)
Decodes to: `
Always encoded — not in the URL unreserved set.
%7B decoded — Left curly brace (U+007B)
Decodes to: {
Always encoded — frequently appears in JSON values passed through query parameters.
%7C decoded — Pipe (U+007C)
Decodes to: |
Always encoded.
%7D decoded — Right curly brace (U+007D)
Decodes to: }
Always encoded — frequently appears in JSON values passed through query parameters.
%7E decoded — Tilde (U+007E)
Decodes to: ~
Unreserved — should not be encoded, but older encoders sometimes do.
%0A decoded — Line feed (LF) (U+000A)
Decodes to: ↵ (LF)
Newline. Always encoded — security-sensitive (CRLF injection).
%0D decoded — Carriage return (CR) (U+000D)
Decodes to: ↵ (CR)
Always encoded — security-sensitive (CRLF injection in HTTP headers).
%09 decoded — Tab (U+0009)
Decodes to: → (tab)
Always encoded.
UTF-8 multi-byte sequences
Any character outside ASCII is encoded as 2–4 percent-encoded bytes (UTF-8). The decoder collapses them back into a single character. A few common ones:
| Encoded | Character | Name |
|---|---|---|
| %C3%A9 | é | e with acute (French, Spanish) |
| %C3%BC | ü | u with diaeresis (German) |
| %E2%80%93 | – | en dash |
| %E2%80%9C | “ | left curly quote |
| %E2%9C%93 | ✓ | check mark |
| %F0%9F%9A%80 | 🚀 | rocket emoji (4-byte sequence) |
Batch decode
Paste many URLs or values, one per line. Useful for log analysis, mass exports, and tracking pixels.
URL Decoding Reference
What URL encoding is, when you need to decode, and how the same value can be decoded differently in different programming languages.
What is URL encoding?
URLs can only contain a small set of ASCII characters. Anything else — spaces, accented letters, emoji, symbols with special meaning like ? & = #, or bytes outside ASCII — must be written as %XX where XX is a two-digit hex pair. URL decoding is just the reverse: turning %20 back into a space, %C3%A9 back into é, and so on.
When do I actually need to decode?
- Reading a value out of a URL query string in your logs
- Debugging an email link, an OAuth redirect, or an SSO callback
- Inspecting tracking pixels in marketing tools
- Parsing a webhook payload that was sent as
application/x-www-form-urlencoded - Diffing two URLs to see what actually changed (decoded form is easier to read)
Full URL vs. value-only decoding
The two decoding modes in this tool correspond to the JavaScript built-ins decodeURI() and decodeURIComponent(). Full URL mode preserves URL-structural characters (/ : ? & = #) so the decoded result is still a valid URL. Value / parameter mode decodes everything — use it when your input is one piece extracted from a URL, like a single query value.
The + vs %20 question
In strict URL syntax, a literal + in a path or query is just a plus sign. But HTML forms submit data as application/x-www-form-urlencoded, where +is shorthand for a space. So if your input came from a form submission, an analytics pixel, or anywhere that calls itself "form-encoded", toggle Treat + as space. JavaScript's built-in decode functions do not do this for you.
URL encoding vs HTML entities
These are different things people often confuse. URL encoding looks like %26. HTML entities look like &. If you have & in your input, you need an HTML decoder, not a URL decoder. The two encodings can co-exist (HTML attributes hold URLs that hold percent-encoded values), but each layer has to be peeled with the right tool.
Decoding URLs in different languages
JavaScript / TypeScript
// Full URL (preserves syntax chars)
decodeURI('https://x.com/a%20b')
// Single value
decodeURIComponent('hello%20world')
// Form-encoded (+ is space)
new URLSearchParams('q=hello+world').get('q')Python
from urllib.parse import unquote, unquote_plus
# Standard percent decoding
unquote('hello%20world') # 'hello world'
# Form-encoded (+ -> space)
unquote_plus('hello+world') # 'hello world'PHP
// Standard percent decoding
rawurldecode('hello%20world');
// Form-encoded (+ -> space)
urldecode('hello+world');Ruby
require 'cgi'
require 'uri'
URI.decode_www_form_component('hello+world')
# 'hello world'
CGI.unescape('hello+world')Go
import "net/url"
s, _ := url.QueryUnescape("hello+world")
// "hello world"
p, _ := url.PathUnescape("hello%20world")
// "hello world"Bash / Shell
# With python
python3 -c "import sys, urllib.parse as p;
print(p.unquote(sys.argv[1]))" 'hello%20world'
# With jq
echo '"hello%20world"' | jq -r '@uri | .'
# Pure shell
printf '%b' "${input//%/\\x}"Gotchas that bite developers
Double encoding
Pipelines that pass URLs as parameters within other URLs often end up encoding the same data twice. If your decoded output still has %XX in it, run it through the decoder a second time. The tool above will prompt you when this happens.
Malformed sequences
A lone % or a sequence like %2G (G isn't hex) will throw URIError: malformed URI. Encode literal percent signs as %25.
Security: never trust decoded input
Decoded data may contain < > " or path-traversal tokens like ../. Always validate before using decoded values in HTML, SQL, file paths, or shell commands.
Path components vs query values
/ inside a path segment must be encoded as %2F — otherwise a parser treats it as a new path level. Same for ?, #, and & inside a value.
URL decoder FAQs
Common questions about URL decoding, percent-encoded characters, and URL formats.