Developer Tools
URL Encode / Decode
Encode text for safe use in a URL or query string, and decode percent-encoded URLs back to readable text. Handles spaces, symbols and Unicode. Runs in your browser.
Component escapes everything with a meaning in a URL, including : / ? & = — right for a single query value.
How to percent-encode or decode a string
- Pick Encode or Decode, then a scope: Component for a single value such as a query parameter, or Whole URL for an address that must stay clickable. The box opens with a sample URL containing a space and an Arabic letter so you can see both kinds of escaping at once.
- Paste the value you want to encode, or the %-encoded string you want to read, into the box.
- Press URL-encode or URL-decode. The result appears below in its own box.
- Copy it with the Copy button, or switch modes and paste the result back in to go the other way.
Component scope versus Whole URL scope
In Component scope, encoding runs the JavaScript function encodeURIComponent and decoding runs decodeURIComponent. The component version escapes every character that has a meaning in a URL, including the colon, slashes, question mark, ampersand and equals sign. The sample input https://example.com/search?q=hello world&lang=ع therefore comes out as https%3A%2F%2Fexample.com%2Fsearch%3Fq%3Dhello%20world%26lang%3D%D8%B9. That is exactly right when the whole address is itself a value, such as a redirect_uri or a url= parameter, and exactly wrong if you wanted a link you can click.
Whole URL scope switches to encodeURI and decodeURI, which leave the structural characters alone. The same sample then becomes https://example.com/search?q=hello%20world&lang=%D8%B9, an address you can paste straight into a browser. The catch is that encodeURI cannot tell an ampersand inside a value from one that separates parameters, so a value that itself contains & or = still has to be encoded on its own in Component scope and pasted into the address by hand.
| Character | Component (encodeURIComponent) | Whole URL (encodeURI) |
|---|---|---|
| space | %20 | %20 |
| & | %26 | & (unchanged) |
| = | %3D | = (unchanged) |
| / | %2F | / (unchanged) |
| ? | %3F | ? (unchanged) |
| : | %3A | : (unchanged) |
| # | %23 | # (unchanged) |
| + | %2B | + (unchanged) |
| % | %25 | %25 |
| ü | %C3%BC | %C3%BC |
Characters that are never escaped
Letters A to Z and a to z, the digits, and the nine marks - _ . ! ~ * ' ( ) pass through untouched. RFC 3986 lists ! * ' ( ) among the reserved sub-delimiters, so a stricter encoder such as Python's quote with an empty safe set would escape them; this one follows the ECMAScript definition and leaves them alone. If a service rejects a value because of an apostrophe or parenthesis, replace those by hand with %27, %28 and %29.
How non-ASCII text is escaped
Anything outside ASCII is converted to UTF-8 first, and each byte becomes a percent sign followed by two hex digits. The Arabic letter in the sample is two bytes, D8 B9, hence %D8%B9. A u-umlaut is %C3%BC, also two bytes. A four-byte emoji such as the grinning face becomes %F0%9F%98%80, twelve characters for one symbol, which is why encoded URLs with emoji in them get long so quickly. Decoding requires those byte sequences to form valid UTF-8: an old-style %E9 for é on its own is rejected with the invalid string error. Encoding can fail in one case only, a lone surrogate (half of a four-byte character left behind by a careless substring cut), which cannot be expressed in UTF-8 and gets its own message saying the text can't be encoded.
Decoding behaviour and its edge cases
- A plus sign stays a plus sign. Form submissions (application/x-www-form-urlencoded) write spaces as +, but decodeURIComponent does not translate them, so hello+world decodes to hello+world. Replace the plus signs with spaces before decoding form data.
- A percent sign that is not followed by two hex digits, as in 100% off, makes decoding fail with the message That isn't a valid URL-encoded string. Encode such text first, or write it as 100%25.
- Only one layer is removed per press. A double-encoded value such as hello%2520world decodes to hello%20world; paste that back in and press again to reach hello world.
- Decoding never throws on text that has no escapes at all, so pasting a plain sentence simply returns it unchanged.
- In Whole URL scope, decodeURI deliberately keeps the escapes for reserved characters: %3A, %2F, %3F, %26, %3D, %23, %2B, %2C, %3B and %40 stay exactly as written so the decoded address keeps its structure. Switch to Component scope when you want those turned back into characters as well.
Typical jobs for this encoder
The most common one is preparing a query value that contains spaces, ampersands or non-Latin letters before it goes into a link, a tracking template or a webhook URL. OAuth and SSO flows need the redirect address itself encoded as a parameter, which is precisely what the component function does. The mailto scheme uses the same escaping for subject and body text. In the other direction, decoding lets you read a long affiliate or tracking link, a referrer value in a log line, or the state parameter an identity provider sent back.
Frequently asked questions
What does URL encoding do?
URL encoding (percent-encoding) replaces unsafe characters — like spaces, &, ? and non-English letters — with % codes so they can be sent safely inside a URL or query string.
When should I URL-encode something?
Encode any value you place into a URL's query string, such as search terms or parameters, so special characters don't break the link or change its meaning.
Why does encoding my full URL break the https:// part?
You are in Component scope, which escapes the colon and slashes as %3A and %2F because it treats the text as a parameter value. Switch to Whole URL scope and the address keeps its structure while spaces and non-ASCII letters are still escaped.
Why is the plus sign not turned into a space when I decode?
Only HTML form encoding uses + for a space; the percent-encoding functions this tool uses treat + as a literal plus. Swap the plus signs for spaces yourself before decoding form data.
What happens with a double-encoded string like %2520?
One press removes one layer, so %2520 becomes %20. Copy the result into the input and decode again to get the space.
Why do I get an error when decoding text with a percent sign?
A percent sign must be followed by two hex digits. Text such as 50% done contains a bare percent sign, so decoding stops with an error. Encode it instead, which turns the sign into %25.
Explore
113 tools. Zero uploads. One place.
Every tool opens instantly, works on your phone and keeps your files on your device.
URL Encode / Decode guides
Related tools
JSON Formatter
Developer Tools
Format, validate and minify JSON instantly.
Open toolBase64 Encode / Decode
Developer Tools
Encode text to Base64 or decode it back.
Open toolUUID Generator
Developer Tools
Generate random UUID (v4) identifiers in bulk.
Open toolColor Converter
Developer Tools
Convert colors between HEX, RGB and HSL.
Open tool