URL Encoder
Percent-encode a value — and pick the encoding that matches where it is going.
Text
Encoded
Why one value breaks a URL and another does not
A support engineer pastes a note into a lookup URL — note=SIM swap & re-provision — and the API comes back with a note that reads SIM swap and a second, empty parameter called re-provision. Nothing errored. The & did exactly what an & does in a query string: it started a new parameter. Percent-encoding is how you say "this ampersand is part of my data, not part of the URL".
The mechanics are simple enough. Any byte can be written as % followed by two hex digits, so a space becomes %20 and an ampersand becomes %26. RFC 3986 §2.1 defines the mechanism, and §2.2 lists the characters that are reserved because they carry structural meaning somewhere in a URL.
The part that trips people is that there is not one encoding, there are three, and they disagree on purpose. encodeURI is for a whole URL, so it deliberately leaves : / ? # & = alone — encode those and you would destroy the address. encodeURIComponent is for one piece of a URL, so it escapes them. Form encoding is a third thing again, defined by the URL Standard, and it writes a space as +.
The selector above the output picks between them and the result changes as you switch, so you can see the difference on your own value rather than trusting a table. Everything runs in the page — nothing you paste is uploaded.
Encoding a value
- Paste the value, not the URL – Paste the piece that needs escaping — the search term, the note, the file path — rather than the whole address. Encoding a whole URL under the "One value" setting turns its slashes into
%2Fand gives you something no server will route. - Choose where it is going – One value for a query parameter or a path segment. Whole URL when you have a complete address containing spaces or accents and want the structure left intact. Form field when you are hand-building a request body for
application/x-www-form-urlencoded. - Turn on RFC 3986 if the value hits a stricter parser –
encodeURIComponentleaves! ' ( ) *unescaped because it was written against the older RFC 2396, where those were ordinary marks. Most of the time nothing notices. Turn the toggle on when the value lands somewhere that treats them as syntax — an OAuth signature base string is the usual culprit. - Read the counter before you commit to it – The chip shows how many characters were escaped and what the value grew to. An emoji is four bytes, so it becomes twelve characters. That matters when the total URL is close to a limit.
- Copy it into place – Copy takes the encoded value; Download saves it as a text file. If you need to check it, paste the result into the URL decoder and confirm you get back exactly what you started with.
Encode the value, then assemble the URL — never the other way round. If you build the string first and encode afterwards, you cannot tell your data's ampersands from the URL's own, and neither can the encoder.
The same string, three encodings
The clearest way to see the difference is on a URL that is about to become a value inside another URL — an OAuth redirect_uri, a callback, a next= parameter. Click Sample to load it. One value produces ten escapes, Whole URL produces one, and only one of those is safe to hand to the outer URL.
https://api.telco.example/lookup ?msisdn=+447700900112¬e=SIM swap # a callback URL, about to be stuffed # into a redirect_uri parameter
# One value — 10 escapes. Correct. https%3A%2F%2Fapi.telco.example %2Flookup%3Fmsisdn%3D%2B4477009… # Whole URL — 1 escape. The ? and & # stay structural, so the outer URL # swallows them. https://api.telco.example/lookup ?msisdn=+447700900112¬e=SIM%20swap # Form field — like One value, but # the space is + instead of %20 …%26note%3DSIM+swap
When you need this
A search term with a space, a slash or an ampersand
The everyday case. apn=internet.telco.uk/mms looks fine until the slash is read as a path separator by something in the chain. Encode the value, and %2F arrives as a slash in the data rather than a boundary in the URL.
Non-English text and emoji
A name like Linnéa or an em dash in a note is not ASCII, so it has to travel as UTF-8 bytes. é is two bytes and becomes %C3%A9; a rocket emoji is four and becomes %F0%9F%9A%80. This page encodes as UTF-8 throughout, which is what every modern server expects — see RFC 3629 for the byte layout.
A phone number that starts with +
The single most reported "the API lost my data" bug in telecoms. An MSISDN written +447700900112 goes into a query string as-is, the receiving end reads it as form-encoded, and the + becomes a space — so you get 447700900112 with a leading blank. Encode it and the plus becomes %2B, which survives either reading.
Hand-building a form body for curl
When you are reproducing a browser request with curl --data, the body is form-encoded, not component-encoded. The Form field setting produces exactly what the browser would have sent, including the + for spaces and the escaping of ! ' ( ) that the URL Standard serialiser performs.
Putting a URL inside a URL
Redirect and callback parameters carry a whole address as a value, and that address has its own ? and &. Every one of them has to be escaped or the outer URL absorbs them — the worked example above shows the same callback under all three settings. Use One value here, always. Reaching for Whole URL feels right because the value is a URL, and it is the wrong answer: it leaves the delimiters structural, and it also leaves a leading + in a phone number alone, which the next layer is entitled to read as a space.
What this page does
- Three encodings side by side —
encodeURIComponent,encodeURIand the form serialiser — switchable without retyping. - Correct UTF-8 for accented text, CJK and emoji, so multi-byte characters become the right sequence of escapes rather than mojibake.
- An RFC 3986 toggle that also escapes
! ' ( ) *, for the parsers that care. - A live count of how many characters were escaped and how much the value grew, with a nudge when the result gets long enough to worry about.
- A refusal to guess when the input holds a broken surrogate pair, rather than silently substituting a replacement character the way form encoding does.
- Everything runs in your browser. Nothing you paste is sent anywhere.
Questions people actually ask
encodeURI or encodeURIComponent — which one do I want?
If you are encoding part of a URL, you want encodeURIComponent — the "One value" setting here. If you have a complete URL that happens to contain spaces or accents and you want to make it legal without breaking its structure, you want encodeURI. The rule of thumb: are you encoding a thing that goes into a URL, or a URL itself? This is the most-asked JavaScript question on the subject and the canonical Stack Overflow thread is worth reading once properly.
Why did my space become a + instead of %20?
Because you have the Form field setting on. application/x-www-form-urlencoded is a slightly different encoding that predates the modern URL rules, and in it a space is written +. Both are correct — for different destinations. A query string a browser built from a form will use +; a URL built by encodeURIComponent will use %20. Anything that parses query strings properly accepts both.
Should I encode the slashes in a path?
Only if the slash is part of a single path segment rather than a separator between segments. A file path used as an identifier — logs/2026-08/hss.log — has to have its slashes escaped to %2F, or the server sees three segments. Be aware that some servers reject or normalise %2F in paths for security reasons, so this is worth testing rather than assuming.
Do I need to encode a value twice if it passes through two services?
No, and doing it is a real bug with a name: double encoding. Each layer should decode what it receives and encode what it sends. If you encode twice by hand, a space becomes %2520 and the far end gets the literal text %20 rather than a space. The decoder flags that pattern when it sees it.
Is this the same as HTML escaping or Base64?
No — three different jobs that get confused constantly. Percent-encoding makes a value safe inside a URL. HTML escaping (&) makes it safe inside a document. Base64 makes arbitrary bytes survive a text channel. A value can need more than one of them, applied in the right order, and applying the wrong one is why & sometimes shows up literally on a page.
What happens to a newline or a tab?
They are bytes like any other and become %0A and %09. That is usually what you want, but it is worth knowing that a multi-line value in a query string is legal and just looks strange in a log. If you are encoding something structured with newlines in it, converting it to a compact single-line form first usually makes the URL easier to read.
Related tools
Specifications and references
- RFC 3986 §2 — Characters – The definition of percent-encoding, and the reserved set that makes it necessary
- WHATWG URL Standard — percent-encode sets – What browsers actually implement, which is more nuanced than the RFC
- MDN — Percent-encoding – The short version, with the character tables