How to URL Encode and Decode a URL
You paste a link into a chat app and it arrives broken. You add a customer name to a query string and the page returns the wrong result. You share a search URL and everything after the first space disappears.
The cause is almost always the same: a URL can only legally contain a small set of characters, and something in your link isn't one of them. URL encoding — properly called percent-encoding — is the fix. It swaps unsafe characters for a % followed by two hexadecimal digits, so blue shoes becomes blue%20shoes and survives the trip intact.
This guide covers what percent-encoding actually does to your text, the one decision that trips up most people (encode the whole URL or just one piece of it?), the traps that silently corrupt data instead of throwing an error, and a full reference table. You can encode or decode anything as you read using FileNaut's free URL Encoder/Decoder — it runs entirely in your browser, so nothing you paste is uploaded anywhere.
---
What URL encoding actually does
A URL is allowed to contain letters, digits, and a handful of punctuation marks. Everything else has to be represented indirectly.
Percent-encoding works in two steps:
- The character is converted to its bytes using UTF-8.
- Each byte is written as
%plus that byte's two-digit hex value.
A space is byte 0x20, so it becomes %20. An ampersand is 0x26, so it becomes %26. That's the entire mechanism — there's no compression, no encryption, and no secret. Anyone can read a percent-encoded string straight back.
This is also why non-English characters expand. é is two bytes in UTF-8, so it encodes to %C3%A9. Chinese characters are three bytes (中 → %E4%B8%AD), and emoji are four (👍 → %F0%9F%91%8D). A name in Japanese can triple in length once encoded — worth knowing if you're near a URL length limit.
> Encoding is not security. Percent-encoding is a transport format, not a protection layer. If you need to obscure or transport binary data, that's a different job — see Base64 Encode/Decode — and neither one is encryption.
---
Which characters get encoded
Only these characters are ever left untouched: A–Z, a–z, 0–9, and - _ . ~ ! * ' ( ).
Everything else in the table below is transformed. The two columns matter because they correspond to the two different jobs described in Section 5.
| Character | Name | As a URL part | In a whole URL | |
|---|---|---|---|---|
| (space) | space | %20 | %20 | |
" | double quote | %22 | %22 | |
# | hash / fragment | %23 | # (kept) | |
$ | dollar | %24 | $ (kept) | |
% | percent | %25 | %25 | |
& | ampersand | %26 | & (kept) | |
+ | plus | %2B | + (kept) | |
, | comma | %2C | , (kept) | |
/ | slash | %2F | / (kept) | |
: | colon | %3A | : (kept) | |
; | semicolon | %3B | ; (kept) | |
< | less than | %3C | %3C | |
= | equals | %3D | = (kept) | |
> | greater than | %3E | %3E | |
? | question mark | %3F | ? (kept) | |
@ | at sign | %40 | @ (kept) | |
[ | open bracket | %5B | %5B | |
\ | backslash | %5C | %5C | |
] | close bracket | %5D | %5D | |
^ | caret | %5E | %5E | |
` `` | backtick | %60 | %60 | |
{ | open brace | %7B | %7B | |
| `\ | ` | pipe | %7C | %7C |
} | close brace | %7D | %7D | |
~ | tilde | ~ (kept) | ~ (kept) |
The middle column is what FileNaut's encoder produces. Look at the rows where the columns disagree — #, &, /, :, ?, =, @ — because those are the characters that build a URL. That difference is the whole of Section 5.
---
How to URL encode online (step by step)
- Open the URL Encoder/Decoder.
- Make sure the Encode tab is selected — it's the default.
- Paste your text into the Input URL box on the left. Paste the value you want to make safe (a search term, a name, a redirect target), not necessarily the whole address — Section 5 explains which one you need.
- Click Encode URL.
- The percent-encoded result appears on the right. Click Copy to put it on your clipboard.
Decoding is the same flow in reverse: click the Decode tab, paste the encoded string, click Decode URL. The tool processes everything locally in your browser — the text never leaves your device, which matters when the URL contains a session token, an internal hostname, or a customer's email address.
To go the other way on a value you don't recognise at all, check whether it's percent-encoded (lots of % pairs) or Base64 (long, ends in =) before picking a tool.
---
The one decision that matters: whole URL or one part?
This is where most broken links come from.
Encoding a single part (a query value, a path segment, a search term) has to escape &, =, ?, / and #, because if it doesn't, those characters will be mistaken for URL structure.
Encoding a whole URL must not escape them — those characters are the structure.
Watch what happens to the same address:
Original:
https://example.com/my page?q=blue shoes&x=a+b#sec 1
Encoded as a whole URL (correct — structure preserved):
https://example.com/my%20page?q=blue%20shoes&x=a+b#sec%201
Encoded as a single part (structure destroyed):
https%3A%2F%2Fexample.com%2Fmy%20page%3Fq%3Dblue%20shoes%26x%3Da%2Bb%23sec%201That second result isn't a URL any more. Paste it into a browser and you'll get a search, not a page.
FileNaut's encoder does part-encoding (the middle column of the table above). That's the right default, because part-encoding is what you need 90% of the time — and because it's the only one of the two that is ever required. So:
- Encoding a search term, a name, an email, a redirect target, a filename? Paste just that value. The tool does exactly what you want.
- Trying to fix a whole URL that has spaces in it? Don't paste the whole thing. Paste only the broken piece — the path segment or the parameter value — encode it, and put it back into the URL by hand.
Here's the correct workflow for building a link. Say you want to search for blue shoes & socks:
- Encode only the search term →
blue%20shoes%20%26%20socks - Assemble the URL yourself →
https://example.com/search?q=blue%20shoes%20%26%20socks
If you had encoded the whole URL as one part, the ? and = would have become %3F and %3D, and the server would have seen one long nonsense path instead of a search.
---
Decoding, and the `+` trap
Decoding reverses the process: blue%20shoes becomes blue shoes, caf%C3%A9 becomes café.
But there's a catch that catches almost everyone. A plus sign in a query string usually means a space — and standard URL decoding won't convert it.
Input: blue+shoes
Output: blue+shoes ← unchangedThis is not a bug in the tool; it's a genuine ambiguity in how the web evolved. HTML forms submit data as application/x-www-form-urlencoded, a format that encodes spaces as +. Percent-encoding — the standard used everywhere else — encodes spaces as %20. Both are legitimate, and a decoder cannot tell which one produced the string it's given.
How to handle it: if you're decoding something that came out of a form submission or a search box (it'll look like q=blue+shoes&cat=men), replace every + with %20 before pasting it into the decoder. If you're decoding an API response, an OAuth value, a Base64 payload, or an email address, leave + alone — there it's a real plus sign, and converting it would corrupt the value. user+tag@example.com is a valid address, and turning that + into a space breaks it.
---
The five traps that silently corrupt data
These are ranked by how often they cause real damage. What makes them dangerous is that four of the five produce no error at all — just a wrong answer.
**1. Double encoding — %2520**
Encoding an already-encoded string encodes the % itself:
Original: blue shoes
Encoded once: blue%20shoes
Encoded twice: blue%2520shoes%25 is a literal %, so %2520 decodes back to %20 — the text %20, not a space. Your user sees "blue%20shoes" printed on the page. If you ever see %25 in a live URL, something has been encoded one time too many. Decode it once and check.
2. Encoding the whole URL as a part — covered in Section 5. Symptom: https%3A%2F%2F at the start. The link becomes unclickable and search engines treat it as a broken destination.
**3. A literal % breaks decoding entirely**
% is the escape character, so a raw one is invalid input:
Input: 100% cotton
Output: Error: Invalid input for decoding.This is the one trap that does announce itself. If you need a literal percent sign in a URL, it must be encoded as %25 first. Note that the error text appears in the result box, so don't copy it into your link by accident.
**4. !, ', (, ) and * are left unencoded**
Standard URL encoding treats these five as safe, but RFC 3986 lists them as reserved sub-delimiters. Nearly always harmless — but if you're generating an OAuth 1.0 signature, building an AWS Signature V4 request, or hitting a strict API, the signature will fail because the server encoded them and you didn't. Those specs require you to percent-encode all five manually: ! → %21, ' → %27, ( → %28, ) → %29, * → %2A.
5. Encoding after concatenating instead of before
The order is not optional. Build your value, encode the value, then join it into the URL. If you assemble the full string first and encode afterwards, you get trap #2. If a user's input contains an & and you never encode it at all, they can inject an extra parameter into your URL — a real security issue, not just a display bug.
---
Where this actually bites you
- Query parameters — any search term, filter, or user-supplied value with a space,
&, or#in it. - UTM tracking links — campaign names like
spring sale 2026must bespring%20sale%202026, or your analytics tool splits the campaign into two. - Redirect parameters —
?next=https://example.com/dashboardneeds the target URL encoded as a part, precisely because it contains://and?. This is the one case where you deliberately wanthttps%3A%2F%2F. - **
mailto:links** — subject lines and bodies need encoding;%0Agives you a line break. - API requests — a filter like
name=O'Brien & Sonsbreaks the request unless the value is encoded. - Filenames in URLs —
Q3 report (final).pdfbecomesQ3%20report%20(final).pdf. This is common enough that many teams just avoid spaces in filenames entirely. - Non-Latin content — Cyrillic, Arabic, Chinese and emoji all work fine in modern browsers, which display them decoded while sending them encoded.
---
Doing it in code
Every language ships this. The trap is that most offer two functions, and picking the wrong one causes Section 5's problem.
// JavaScript — encodeURIComponent for a PART, encodeURI for a WHOLE URL
encodeURIComponent('blue shoes & socks'); // 'blue%20shoes%20%26%20socks'
encodeURI('https://example.com/my page'); // 'https://example.com/my%20page'
decodeURIComponent('blue%20shoes'); // 'blue shoes'
// Safest: let the URL API assemble it for you
const u = new URL('https://example.com/search');
u.searchParams.set('q', 'blue shoes & socks');
u.toString(); // encoding handled automatically# Python — quote() keeps '/' by default; quote_plus() uses + for spaces
from urllib.parse import quote, quote_plus, unquote, urlencode
quote('blue shoes & socks', safe='') # 'blue%20shoes%20%26%20socks'
quote_plus('blue shoes') # 'blue+shoes' (form style)
unquote('blue%20shoes') # 'blue shoes'
urlencode({'q': 'blue shoes'}) # 'q=blue+shoes'// PHP — rawurlencode is RFC 3986 (%20); urlencode is form style (+)
rawurlencode('blue shoes'); // 'blue%20shoes'
urlencode('blue shoes'); // 'blue+shoes'
rawurldecode('blue%20shoes');# Command line
curl --data-urlencode "q=blue shoes & socks" https://example.com/search
jq -rn --arg v 'blue shoes' '$v|@uri' # blue%20shoesRule of thumb across all of them: the function whose name mentions component, raw, or safe='' is the part-encoder — that's usually the one you want. The one that produces + for a space is the form-encoder, and it belongs only in a form body.
---
Tips
- Encode values, assemble URLs. Never encode a URL you've already assembled.
- Use your language's URL builder (
new URL(),urlencode(), a request library'sparamsargument) instead of string concatenation. It removes the whole class of bug. - **If you see
%25, suspect double encoding** — decode once and look again. - **If you see
https%3A%2F%2Fin a browser bar, something over-encoded a whole URL** — the exception is a deliberate redirect parameter. - **Convert
+to%20before decoding form data**, and leave+alone in emails, tokens and Base64. - **Encode
! ' ( ) *by hand for OAuth and AWS signatures.** Standard encoders skip them. - Test the round trip. Encode, decode, and confirm you get your original string back exactly. Anything lost or changed means you've hit one of the Section 7 traps.
---
FAQs
What does %20 mean in a URL?
▼
What's the difference between %20 and + for a space?
▼
Should I encode the whole URL or just part of it?
▼
Why does my decoded URL show %2520?
▼
Why do I get "Invalid input for decoding"?
▼
Is URL encoding the same as encryption?
▼
Why does one accented letter become six characters?
▼
Is it safe to paste a URL with a token into an online encoder?
▼
Why does my OAuth or AWS signature fail even though I encoded everything?
▼
Do I need to encode a URL before putting it in an email or chat?
▼
---
Approx. word count: ~2,300 words of prose (excluding code blocks and metadata).
---
# DEPLOY NOTES — read before publishing
Ready to try it?
Use the tool right now — free, no signup, no upload.