URL encoder, decoder and parser

Encode, decode and parse URLs, and edit the query string.

Encodes everything except letters, digits and - _ . ! ~ * ' ( ). Use it for one value (encodeURIComponent).

What this tool does

A URL can only carry a small set of plain characters. Anything else, such as a space, an accent, an emoji or a character that has a meaning in URL syntax, is written as a percent sign and two hex digits for each byte: a space is %20, "é" is %C3%A9. This tool has three tabs. Encode turns text into that form, Decode turns it back and tells you exactly which escape is broken, and Parse a URL splits an address into scheme, user, host, port, path, query and fragment, lists the query parameters in a small editor, and rebuilds the URL as you change them.

Three kinds of encoding

The same text can be encoded three ways, and picking the wrong one is the most common mistake.

  • Component (encodeURIComponent) encodes everything except letters, digits and - _ . ! ~ * ' ( ). Use it for one value that goes inside a URL, such as a search term. a/b?c=d&e becomes a%2Fb%3Fc%3Dd%26e.
  • Whole URL (encodeURI) also leaves ; , / ? : @ & = + $ # alone, so a complete address keeps its shape: the same text stays a/b?c=d&e. It is wrong for a single value, because an & or = inside it would be read as syntax. It does encode [ and ], so it breaks an IPv6 address.
  • Form is what HTML forms and URLSearchParams write: a space becomes +, and ~ ! ' ( ) are encoded as well. "café au lait & crème" is caf%C3%A9+au+lait+%26+cr%C3%A8me in form style and caf%C3%A9%20au%20lait%20%26%20cr%C3%A8me in component style.

All three work on UTF-8 bytes, so an emoji, which is a surrogate pair in JavaScript, becomes four bytes: 😀 is %F0%9F%98%80. A lone half of a surrogate pair has no UTF-8 form, so JavaScript's own function throws "URI malformed". This tool reports the position instead.

Decoding and what can go wrong

Decoding reverses each escape. A plus sign is only a space in form style, and %2B is always a plus. Decoding fails in two ways. A % that is not followed by two hex digits, as in 100% or %zz, is a broken escape. And escapes that do not form valid UTF-8, such as %C3%28 (a two-byte start followed by a plain parenthesis), are not text. The tool names each problem with its position and keeps the undecodable part as written, so you can see where it is instead of getting an error and nothing else. Switch on "Stop at the first error" if you prefer no output when something is wrong. If the decoded text still contains escapes, such as %2520 becoming %20, it was probably encoded twice, and a button decodes it again.

Taking a URL apart

The parser first splits the address exactly as written, following RFC 3986, so nothing is hidden. Then it compares each part with what the browser's URL parser makes of it and shows the difference underneath. For https://user:pw@example.com:443/a/./b?q=a+b#top the browser drops the default port 443, resolves the ./ in the path and, for an address such as münchen.de, writes the host as xn--mnchen-3ya.de. Addresses without a scheme are read as relative references, and localhost:3000/x is flagged because it reads as a scheme called localhost. An empty query (?) is not the same as no query, and the table keeps that difference.

Editing the query string

Each parameter is a row with a name and a value. Order and duplicate names are kept (?q=1&q=2), a name without = stays that way until you type a value, and an empty value stays empty. Parameters you do not touch come back exactly as written; edited ones are encoded with %20 for spaces, or with + if the query already used it. Reorder, remove or add rows and copy the rebuilt URL. The Base64 tool and the JSON formatter help when a parameter holds encoded data, and the regex tester is useful for picking URLs out of text.

URLs often carry tokens and personal data. Everything here runs in your browser and nothing is uploaded, and no link is ever opened for you.

Frequently asked questions

What is the difference between encodeURI and encodeURIComponent?

encodeURIComponent encodes the characters that have a meaning in URL syntax (/ ? : @ & = + $ # , ;), so it is right for a single value. encodeURI leaves them alone, so it is right for a complete address. Using encodeURI on a value lets an & or = inside it change the meaning of the URL.

Should a space be %20 or +?

In a path, always %20. In a query string a + means a space only in form encoding, which is what HTML forms and URLSearchParams use. Many servers read both in the query, but %20 is the safer choice, and %2B is always a literal plus.

Why does decoding say my text is not valid UTF-8?

Percent escapes stand for bytes, and the bytes have to make valid UTF-8 text. A stray byte such as %FF, or a start byte such as %C3 not followed by a continuation byte, is not text. The text may be in an older encoding such as Latin-1, where %E9 is é.

Why does my decoded text still contain % signs?

Either it was encoded twice (%2520 decodes to %20, which decodes to a space), or the percent signs are real. A button appears when the result still holds valid escapes, so you can decode again.

Does the parser change my URL?

No. It shows the parts exactly as you wrote them and, underneath, what the browser would make of them: a dropped default port, resolved dot segments, lower-case host, punycode. The rebuilt URL keeps untouched parts byte for byte, apart from empty segments such as && that are dropped.

Is the URL sent anywhere?

No. All of it is computed in your browser, and links are shown as text, never opened or fetched.