URL Encoder & Decoder
Component escapes / ? & = too — use it for a single query value. Full URL keeps them, so the URL still parses.
Nothing you enter here is stored, logged or shared.
Percent-encode text for use in a URL, or decode it back. Choose whether you are encoding one query value or an entire URL, because the two need different escaping.
How to use
- Choose encode or decode.
- When encoding, pick Component for a single value or Full URL for a whole address.
- Paste your text and copy the result.
Why there are two modes
RFC 3986 divides the characters that can appear in a URL into two groups. Unreserved characters - the letters, the digits, and the four marks - _ . ~ - always mean themselves and are never encoded. Reserved characters mean something structural: the colon after the scheme, the slashes between path segments, the question mark that opens the query, the ampersand and equals that separate parameters, and the hash that starts the fragment.
The two modes differ only in what they do with that second group. Component mode escapes the reserved characters too, which is what you want when the text is going inside one slot - a single query value, one path segment - and must not be read as structure. Full URL mode leaves them alone, so an entire address survives with its scheme, slashes and separators still doing their job.
Using the wrong one is usually obvious. Run a whole address through Component mode and https://example.com becomes https%3A%2F%2Fexample.com, which no longer resolves. Run a single value through Full URL mode and a stray ampersand in it silently splits your parameter into two.
The characters that cause trouble
Space is the one people meet first. In a path or a query it becomes %20. In an HTML form submission it becomes +, because that is what the older application/x-www-form-urlencoded rules specify, and both conventions are still in daily use. This is why the plus-as-space option exists when decoding: turn it on for a form query string, leave it off for a path, where + is a literal plus sign and turning it into a space corrupts the value.
Ampersand and equals must be escaped inside a value or the server splits the query in the wrong place - the classic case being a search term or a base64 blob that happens to contain one. The hash is never sent to the server at all: everything after it is the fragment, handled by the browser, so an unescaped # inside a parameter silently truncates the request.
Slash inside a value is worth special care. Percent-encoded as %2F it is legal, but a number of servers and proxies decode it before routing, so it can still be read as a path separator. If a value can contain slashes, putting it in the query rather than the path avoids the argument entirely.
Double encoding
Percent-encoding is not idempotent. The percent sign is itself a character that needs encoding, so it becomes %25, and encoding an already-encoded string turns %20 into %2520. That sequence is the visible fingerprint of a URL that went through one encoding step too many, and once you have seen it you will recognise it everywhere.
It happens when a value is encoded by application code and then again by a framework, an HTTP client, or a template that assumed it was receiving raw text. The fix is to remove one of the two steps rather than to decode twice on the receiving end, which merely moves the bug. Decoding here once per layer, and watching whether %2520 becomes %20 and then a space, tells you how many layers there actually were.
Non-ASCII, and what percent-encoding does not cover
Text is converted to UTF-8 first and then each byte is percent-encoded, so a single Japanese character becomes three escape sequences rather than one. This is what the URL standard requires, and it is why Japanese, Chinese, Korean, accented Latin and emoji all round-trip cleanly here.
Domain names are the exception, and the distinction matters. The host part of a URL is not percent-encoded: an internationalised domain is converted with Punycode instead, producing a name beginning xn--. Percent-encoding a hostname produces something that looks encoded and resolves nowhere. Only the path, query and fragment are this tool's business.
The anatomy of a URL
A URL has more parts than most people use: scheme, an optional userinfo section, host, optional port, path, query and fragment. Written out, https://user:[email protected]:8443/a/b?x=1#top contains every one of them. The userinfo form is deprecated for HTTP and browsers strip or warn about it, precisely because it was used to make a hostile host look like a familiar one.
The pieces have different rules. The host is case-insensitive and cannot contain percent-encoding; the path is case-sensitive on most servers; the query has no standard grammar beyond being a string, with key=value pairs separated by ampersands being a convention rather than a specification; and the fragment never leaves the browser.
Relative resolution is the part that surprises people. A link to b/c from /a/page resolves to /a/b/c, but from /a/page/ it resolves to /a/page/b/c - the trailing slash changes the base. This is why a missing or extra trailing slash breaks every relative asset on a page, and why a canonical redirect between the two forms is worth setting up once.
Query strings have conventions, not rules
There is no standard for expressing an array in a query string, which is why every framework does it differently: tags=a&tags=b repeats the key, tags[]=a&tags[]=b adds brackets, and tags=a,b uses a delimiter. All three are valid URLs and each parses to something different depending on the library at the other end.
The same applies to nested structures, booleans and empty values. Does flag= mean false, empty string, or present-but-unset? The answer is whatever the receiving parser decides, so an API that cares should document it and validate rather than assume.
In JavaScript, URLSearchParams handles encoding and repeated keys correctly and should be preferred over building strings by hand. Note that it encodes spaces as plus signs, following the form convention, while encodeURIComponent produces %20 - both decode to a space in a query string, and only one of them does in a path.
The security problems that live in URL handling
An open redirect is an endpoint that sends a visitor to a URL supplied in a parameter without checking it. It is used to make a phishing link start on a domain the victim trusts, and it is a standing finding in security reviews. The fix is an allowlist of destinations, or accepting only paths rather than absolute URLs.
Server-side request forgery is the same class of problem pointed inward: a server fetches a URL a user supplied, and the user supplies an internal address, a cloud metadata endpoint, or a redirect to one. Parsing differences between libraries have been exploited repeatedly here, since two parsers can disagree about which host a crafted URL refers to.
Homograph attacks exploit internationalised domain names, where Cyrillic and Latin characters that render identically produce different hosts. Browsers defend by displaying the punycode form when a name mixes scripts, which is why a suspicious link sometimes shows as xn-- in the address bar. That prefix is worth recognising.
Canonical URLs, duplicates and tracking parameters
The same page is usually reachable at several addresses: with and without www, with and without a trailing slash, over http and https, with an index.html suffix, and with any number of tracking parameters appended. To a search engine those can look like separate pages sharing the same content, which splits whatever authority the page has earned.
Two mechanisms fix it. A 301 redirect resolves the structural variants by picking one form and sending everything else to it. A canonical link element in the head names the preferred address for the variants you cannot redirect, which is mainly the parameter cases.
Tracking parameters deserve a specific note: utm_source and friends are appended by the referring system and produce a distinct URL for every campaign. They belong in analytics, not in the canonical URL, and stripping them client-side after they have been recorded keeps shared links clean. The same goes for the fbclid and gclid parameters that some platforms add automatically.
Designing paths that age well
A URL is a promise, because other people link to it and you do not control those links. That argues for paths that describe the resource rather than the implementation: /guides/subnetting rather than /page.php?id=4718, and no file extensions that tie the address to the technology serving it.
Keep them lowercase and hyphenated. Case sensitivity on the server means /About and /about can be different pages, which is never intentional, and hyphens are the conventional word separator in a slug. Avoid dates in paths unless the content is genuinely an archive, since /2024/pricing looks stale a year later even when the content is current.
When a URL must change, redirect the old one permanently and keep the redirect indefinitely. Breaking links is the one decision on this list that cannot be undone from your side, because the links that matter most are the ones on sites you have never heard of.
Frequently asked questions
- What is the difference between Component and Full URL?
- Component uses encodeURIComponent and escapes the reserved characters / ? & = : as well, which is correct for one query value or path segment. Full URL uses encodeURI and leaves those intact so the address still parses. Encoding a whole URL in Component mode turns https:// into https%3A%2F%2F and breaks it.
- Which one should I use for a query parameter?
- Component. A value containing & or = must be escaped, otherwise the server reads it as a separator and splits your parameter in the wrong place.
- Why does decoding fail with a malformed escape?
- A percent sign must be followed by exactly two hex digits. A stray % (as in "100%") or a truncated sequence like %E4%B8 is not valid, so decoding stops rather than guessing.
- When do I need the plus-as-space option?
- Form submissions encode a space as + rather than %20. Enable it when decoding a query string from an HTML form. Leave it off for path segments, where + is a literal plus.
- Does this handle non-English text?
- Yes. Text is converted to UTF-8 before percent-encoding, so Japanese, Chinese, Korean and emoji all round-trip correctly.
Last updated:
Include the steps, expected result, and actual result. Remove secrets and personal data.
