What is URL encoding?
URL encoding, also called percent-encoding, writes a character that isn't safe in a URL as % and the two hex digits of each of its UTF-8 bytes: a space is %20 and é is %C3%A9. This tool encodes and decodes in four ways (JavaScript's encodeURIComponent and encodeURI, strict RFC 3986, and form encoding), reports invalid escapes by line and column, and breaks a URL into its parts, all in your browser.
Why URL encoding is needed
A URL may contain only a limited set of ASCII characters, and some of those give it its structure: ? starts the query, & separates parameters, = separates a name from its value, and # starts the fragment. A value that contains a space, one of those characters, or a non-ASCII letter must be percent-encoded, each of its UTF-8 bytes written as % and two hex digits, so the URL stays unambiguous. A space becomes %20 and é becomes %C3%A9.
Without encoding, an & inside a value splits it into two parameters, and a # cuts off everything after it as the fragment.
Reserved and unreserved characters
RFC 3986 defines the unreserved characters, A–Z a–z 0–9 - . _ ~, which never need encoding. The reserved characters (: / ? # [ ] @ and ! $ & ' ( ) * + , ; =) can give a URL its structure, so inside a value they're encoded. Everything else, including spaces, %, and every non-ASCII character, is always encoded.
Which encoding to use
Component (JavaScript's encodeURIComponent) is for one value, such as a query parameter or a path segment. It encodes the reserved characters except ! ' ( ) *, which it leaves as they are.
Full URL (encodeURI) is for a whole URL: it keeps the characters that give the URL its structure and encodes spaces and non-ASCII letters. It can't tell a value's own & or ? from the URL's, so encode values with Component before putting them in a URL. Decoding with it (decodeURI) leaves escapes of those structural characters, such as %2F, %3F, and %26, encoded, so a nested URL stays one parameter.
Strict (RFC 3986) encodes everything except the unreserved characters, with uppercase hex. OAuth 1.0 (RFC 5849) and AWS Signature Version 4 require exactly this, and a signature built from encodeURIComponent's output fails whenever a value contains ! ' ( ) or *.
Form (application/x-www-form-urlencoded) is how HTML forms and URLSearchParams encode data: a space becomes +, and everything except A–Z a–z 0–9 * - . _ is encoded. Decoding it turns + back into a space, as servers do when they read form data and query strings.
Encoding query strings
Encode each name and value separately, then join them with = and &. Encoding the assembled string all at once would escape the & and = that separate the parameters. The URL breakdown shows how a URL's parameters are read, so you can check that a value stayed in one piece.
Errors and double encoding
Decoding reports the exact line and column of an invalid escape: a % without two hex digits after it, or escapes that don't form valid UTF-8, such as a truncated %C3. Form decoding follows the WHATWG URL Standard instead, which keeps a lone % and turns invalid bytes into U+FFFD (�); the tool lists each one.
A value that has been encoded twice has escapes such as %2520, the encoding of %20. The tool points these out, and Decode again decodes the result once more. Encoding text that already has escapes turns each % into %25, which the tool also points out.
How to encode and decode a URL
- 1Choose Encode or Decode. Select Encode to make text URL-safe, or Decode to turn percent-encoded text back into readable text.
- 2Choose the encoding. Component for one value, Full URL for a whole URL, Strict (RFC 3986) for OAuth and AWS signatures, or Form for form data and query strings that use + for spaces.
- 3Enter your text. Paste the text or the encoded value. The result appears as you type, and an invalid escape is reported with its line and column.
- 4Copy the result. Use Copy output. For a URL, the breakdown shows its parts and decoded query parameters.
Examples
Encode a query value (Component)
Input
Ada Lovelace & friends
Output
Ada%20Lovelace%20%26%20friends
Encode for OAuth or AWS (Strict RFC 3986)
Component would leave ' ( ) * and ! as they are: it's%20(really)%20100%25%20*free*!
Input
it's (really) 100% *free*!
Output
it%27s%20%28really%29%20100%25%20%2Afree%2A%21
Encode form data (Form)
Input
hello world & more (100% free!)
Output
hello+world+%26+more+%28100%25+free%21%29
Decode a query string with + for spaces (Form)
Component keeps the +: q=hello+world!
Input
q=hello+world%21
Output
q=hello world!
Encode a whole URL (Full URL)
Input
https://dev-toolbox.io/café menu/?q=crème brûlée&page=2#top
Output
https://dev-toolbox.io/caf%C3%A9%20menu/?q=cr%C3%A8me%20br%C3%BBl%C3%A9e&page=2#top
Decode a URL with a nested URL (Full URL)
decodeURI keeps %3A, %2F, %3F, and %26, so the nested URL stays one parameter.
Input
https://dev-toolbox.io/search?q=hello%20world&redirect=https%3A%2F%2Fexample.com%2Fpath%3Ffoo%3Dbar%26baz%3Dqux#results
Output
https://dev-toolbox.io/search?q=hello world&redirect=https%3A%2F%2Fexample.com%2Fpath%3Ffoo%3Dbar%26baz%3Dqux#results
An invalid escape
Input
100%
Output
Line 1, column 4: "%" isn't an escape: "%" must be followed by two hex digits (a literal % is written %25).
How each encoding writes a character
The output of each encoding for the reserved characters and a few others. A–Z a–z 0–9 - . _ are never encoded.
| Character | Component | Full URL | Strict (RFC 3986) | Form |
|---|---|---|---|---|
| space | %20 | %20 | %20 | + |
| ! | ! | ! | %21 | %21 |
| # | %23 | # | %23 | %23 |
| $ | %24 | $ | %24 | %24 |
| & | %26 | & | %26 | %26 |
| ' | ' | ' | %27 | %27 |
| ( | ( | ( | %28 | %28 |
| ) | ) | ) | %29 | %29 |
| * | * | * | %2A | * |
| + | %2B | + | %2B | %2B |
| , | %2C | , | %2C | %2C |
| / | %2F | / | %2F | %2F |
| : | %3A | : | %3A | %3A |
| ; | %3B | ; | %3B | %3B |
| = | %3D | = | %3D | %3D |
| ? | %3F | ? | %3F | %3F |
| @ | %40 | @ | %40 | %40 |
| [ | %5B | %5B | %5B | %5B |
| ] | %5D | %5D | %5D | %5D |
| ~ | ~ | ~ | ~ | %7E |
| % | %25 | %25 | %25 | %25 |
| é | %C3%A9 | %C3%A9 | %C3%A9 | %C3%A9 |
Frequently asked questions
What is the difference between %20 and + for a space?
%20 is a space anywhere in a URL. + means a space only in application/x-www-form-urlencoded data: form submissions and the query strings servers read the same way. Elsewhere, such as in a path, + is a literal plus sign. Use the Form encoding to write or read + as a space.
When should I use encodeURIComponent versus encodeURI?
encodeURIComponent (Component) for a single value, such as a query parameter: it encodes & = ? / # and other reserved characters. encodeURI (Full URL) for a whole URL: it leaves those structural characters alone, so it can't protect a value's own & or ?.
Why does my OAuth or AWS signature fail?
Both OAuth 1.0 (RFC 5849) and AWS Signature Version 4 require every character except A–Z a–z 0–9 - . _ ~ to be encoded, with uppercase hex. encodeURIComponent leaves ! ' ( ) and * unencoded, so any value containing them signs differently. Use Strict (RFC 3986).
Do I need to encode letters and numbers?
No. Letters, digits, and the unreserved symbols - . _ ~ are always URL-safe and are left unchanged (Form encoding also encodes ~).
What is double encoding?
Encoding text that's already encoded, which turns %20 into %2520. When decoding, the tool points out escapes such as %2520 and can decode once more; when encoding, it points out escapes already in the input.
Why can't this be decoded?
Every % must start an escape of two hex digits, and the escapes must form valid UTF-8. The tool shows the line and column of the first problem, such as a lone % (write a literal % as %25) or a truncated character like %C3.
Why did an & split my value into two parameters?
An unencoded & inside a value is read as the separator between parameters. Encode the value with Component so the & becomes %26; the URL breakdown shows how the parameters are read.
Is my input sent anywhere?
No. Encoding and decoding happen in your browser. The only exception is the Share link button: when you click it, it uploads your input and the encoding you chose so the link can reopen them, so don't share text that contains personal data.
Is it free?
Yes — free and unlimited, with no sign-up.