URL Encoder/Decoder
Free online URL encoder and decoder tool. Encode text for URLs or decode URL-encoded strings instantly. Convert special characters, spaces, and Unicode to percent-encoded format. Perfect for web developers working with query parameters, API endpoints, and URL handling.
URL Encoder/Decoder - Encode and Decode URLs Online
A powerful online URL encoder and decoder tool that helps you encode text for safe use in URLs or decode percent-encoded URL strings back to plain text. Features automatic handling of special characters, spaces, Unicode, and various encoding options. Essential for web developers working with query parameters, API endpoints, form data, and URL manipulation.
Why does URL encoding turn a space into %20?
URLs were originally restricted to a small set of ASCII characters by RFC 1738 (1994) and later RFC 3986 (2005), excluding spaces because they break parsers that delimit components with whitespace. Any character not in the unreserved set (A-Z, a-z, 0-9, and -._~) must be percent-encoded: the byte is written as % followed by its two-digit hexadecimal value. A space is byte 0x20, hence %20. In the older application/x-www-form-urlencoded format used by HTML forms, a space may instead be encoded as +. Both forms decode back to space, but they are not interchangeable in every context: in the query string, + commonly means space, but in the path or fragment, + means a literal +. When in doubt, use %20 everywhere — it is unambiguous across all URL components.
What is the difference between encodeURI and encodeURIComponent?
These two JavaScript functions encode different sets of characters because they target different scopes. encodeURI assumes you are passing a full URL and preserves characters that have a structural meaning: : / ? # [ ] @ ! $ & ' ( ) * + , ; = ~ stay as-is. encodeURIComponent assumes you are passing a single component value (one path segment, one query value, one fragment) that must be embeddable inside a URL without breaking syntax, so it escapes all of those structural characters too. Rule of thumb: build the URL skeleton with encodeURI, but always wrap each user-provided value with encodeURIComponent before concatenating. Using encodeURI for query values is the most common cause of broken search and tracking links — & inside the value will be misread as a parameter separator.
Why doesn't encodeURIComponent escape ! * ' ( ) and how do I make it RFC 3986 strict?
JavaScript's encodeURIComponent was implemented to the older RFC 2396 specification, which classified ! * ' ( ) as marks that did not require escaping. RFC 3986 reclassified them as sub-delims that are reserved in some contexts. For full RFC 3986 compliance, post-process the result yourself: encodeURIComponent(str).replace(/[!*'()]/g, c => '%' + c.charCodeAt(0).toString(16).toUpperCase()). This matters when generating OAuth 1.0a signatures (the spec mandates strict encoding), when building AWS Signature V4 canonical requests, or when interoperating with strict server-side libraries. For typical web links, the JavaScript built-in is fine — browsers and servers tolerate both forms. This tool offers a strict mode that escapes the full reserved set per RFC 3986 section 2.2.
How do non-ASCII characters like Chinese, Vietnamese, or emoji get encoded?
Per RFC 3986 section 2.5 (and earlier IRI specs in RFC 3987), non-ASCII text in URLs must first be converted to UTF-8 bytes and then each byte percent-encoded. The character "é" is two bytes in UTF-8 (C3 A9), so it becomes %C3%A9 — two percent-escapes, not one. The emoji "🎉" is four UTF-8 bytes (F0 9F 8E 89) and becomes %F0%9F%8E%89 — four escapes. Older systems sometimes used Latin-1 or Windows-1252 and produced %E9 for é, which a modern UTF-8 decoder will misinterpret. If you see ? or replacement characters after decoding, the source likely used a non-UTF-8 byte encoding. This tool always encodes and decodes as UTF-8, matching the WHATWG URL Living Standard used by modern browsers.

What characters never need to be encoded in a URL?
RFC 3986 defines the unreserved set: uppercase A-Z, lowercase a-z, digits 0-9, and the four marks - . _ ~. These 66 characters are guaranteed to mean the same thing in every URL component and never require encoding. Reserved characters split into two groups: gen-delims (: / ? # [ ] @) which separate URL components and must be encoded inside a component value, and sub-delims (! $ & ' ( ) * + , ; =) which have special meaning within certain components. Whether sub-delims need encoding depends on context — = and & are critical inside query strings but harmless inside a path segment. A safe shortcut: encode everything outside the unreserved set, and you will always produce a valid URL, even if it is slightly noisier than strictly required.
Why does decoding sometimes leave a literal %25 in my string?
Because % itself must be encoded as %25 to disambiguate it from the percent-encoding escape sequence. If your string contained a literal percent sign that was correctly encoded once as %25, a single decode pass turns it back into %. But if the string was double-encoded — encoded once when stored, encoded again when concatenated into another URL — a single decode leaves %25 in place, which then looks like a stray escape. Double-encoding is rampant in pipelines where a URL is passed as a query parameter to another service: each hop adds another layer. The cure is to decode exactly once per encoding hop, never more, never less. Track every place your code calls an encode function and ensure each has a matching decode on the other side.
Are URL fragments (the part after #) encoded the same as the path or query?
Mostly, but with two key differences. RFC 3986 section 3.5 defines the fragment alphabet as pchar / "/" / "?", which permits / and ? unescaped inside the fragment without ambiguity (there is no further delimiter past #). This means encodeURIComponent will over-escape these characters in fragments, producing %2F and %3F where the unescaped forms are legal. Also, the fragment is never sent to the server in HTTP requests — it is purely client-side — so server-side decoders may never see it. When building deep-link fragments for SPAs that contain JSON or routes, the over-escaping from encodeURIComponent is usually fine; readability suffers but correctness is preserved. This tool exposes a fragment-aware mode that leaves / and ? as-is when targeting that component.
What is the maximum length of a URL, and what happens when I exceed it?
There is no hard limit in the HTTP or URL specifications — RFC 7230 explicitly recommends servers support "a request-line of at least 8000 octets." In practice, browsers, servers, and intermediaries each impose their own caps. Chrome accepts up to 32 KB in the address bar but truncates beyond 2 MB internally. Apache defaults to 8 KB (LimitRequestLine), Nginx to 8 KB (large_client_header_buffers), and IIS to 16 KB. AWS API Gateway caps at 8 KB. Beyond the lowest hop's limit, you get a 414 URI Too Long error. For data over a few hundred bytes, switch to a POST body or shard the data across multiple requests. Heavy query payloads also break analytics, log rotation, and referrer headers — keep URLs under 2 KB for portability.
Key Features
- Encode text to URL-safe percent-encoded format
- Decode percent-encoded URLs back to original text
- Automatic handling of special characters (& = ? # / @ etc.)
- Space encoding options (%20 or +)
- Support for Unicode and international characters
- Handles emoji and multi-byte characters
- One-click swap between encode and decode modes
- Real-time size comparison statistics
- Copy encoded/decoded text to clipboard
- Download results as text files
- Upload text files for encoding/decoding
- Dark mode support
- 100% client-side processing - your data never leaves your browser
- No file size limits
- Works offline after initial load
- Mobile-friendly responsive design
- Clear error messages for invalid input
- No registration or login required
