How to URL Encode a String (%20 vs + Explained)

By • 1 November, 2026 • Developer Tools • 9 minutes read

URL encode any text in seconds with a free tool, learn when a space should be %20 or +, and avoid double encoding. Real tests in JS, Python and PHP.

To URL encode a string, replace every character that isn't a plain letter, digit or one of - . _ ~ with a % and the two-digit hex value of each of its UTF-8 bytes. A space becomes %20 (or + inside a query string), & becomes %26 and é becomes %C3%A9. The fastest way is to paste the text into our free URL encoder and copy the result. It's free, needs no account and works in any browser. The harder part is knowing what to encode and which flavor of encoding the place you're pasting into expects, and that's what most of this guide covers.

Every output below is real. We ran the inputs through the live My Botsy tools on November 1, 2026, and compared them with JavaScript (Node.js 24), Python 3.13 and PHP on the same strings.

How to URL encode a string, step by step

  1. Isolate the value. Encode only the piece of data that goes inside the URL, such as a search term, a file name or a redirect target. Never the whole address (more on that below).
  2. Paste it into the encoder. Open the URL encoder, paste the value and press Submit.
  3. Copy the result. Use the copy button next to the output. Spaces come out as +, which is correct for query strings.
  4. Switch to %20 if it goes in a path. If the value is part of the path (before the ?), replace each + with %20. This is safe because a real plus sign in your text is already encoded as %2B.
  5. Check it. Paste the finished link into the URL parser. It decodes each query parameter back, so you can see whether the server will receive exactly what you meant.

Try it now: paste any value with spaces or an & into the free URL encoder and you'll have a link-safe version in a second.

What actually needs encoding

RFC 3986, the standard that defines URLs, splits characters into three groups:

  • Unreserved, never need encoding: A–Z a–z 0–9 - . _ ~.
  • Reserved, have a job in the URL: : / ? # [ ] @ ! $ & ' ( ) * + , ; =. They must be encoded when they're part of your data rather than the URL's structure. An & in a search term, left raw, starts a new parameter and cuts your value in half.
  • Everything else: spaces, quotes, < >, %, accented letters, emoji and every non-Latin script. These are always encoded, byte by byte, from UTF-8. That's why 東京 turns into 18 characters: %E6%9D%B1%E4%BA%AC.

A real test: one messy string through our encoder

We used a deliberately awkward input that has almost every trap in it:

Café & Bar #1 / 50% off? a+b=c ~ü 東京 Tom's "best" <b>

The URL encoder returned:

Caf%C3%A9+%26+Bar+%231+%2F+50%25+off%3F+a%2Bb%3Dc+%7E%C3%BC+%E6%9D%B1%E4%BA%AC+Tom%27s+%22best%22+%3Cb%3E

What happened to each trap:

InputOutputWhy it matters
space+Form-style encoding, valid in query strings
&%26Otherwise it would start a new parameter
#%23Otherwise everything after it is a fragment the server never sees
%%25Otherwise 50% o could be read as a broken escape
+%2BOtherwise the server reads it as a space
é, ü%C3%A9, %C3%BCTwo UTF-8 bytes each
~%7EUnnecessary but harmless; servers decode both forms
' " < >%27 %22 %3C %3EKept as data, not stripped

That exact output is byte-for-byte what a browser's URLSearchParams produces for the same text, and the same as PHP's urlencode(), which is the function the tool uses. So a value encoded here behaves the same as one a web form would submit.

%20 vs +: which one is right?

Both mean "space", but in different places. %20 is the general percent-encoding from RFC 3986 and works everywhere in a URL. + comes from the HTML form format (application/x-www-form-urlencoded) and only means a space inside the query string. In a path, a + is a literal plus sign: /files/my+report.pdf asks for a file with a plus in its name.

Use this rule of thumb:

  • Query string values (?q=red+shoes): + or %20, both work.
  • Path segments (/docs/red%20shoes): %20 only.
  • mailto: links: %20. The mailto standard (RFC 6068) says spaces should be written as %20, because a + can't be told apart from a real plus sign, as in bill+news@example.org. That's why our mailto link generator writes %20. Our mailto link guide covers the rest.

Which function to use in code

We ran the same test string through the common functions. They disagree on four things: spaces, /, ~ and '.

FunctionSpace/~'Leaves & # ? raw?
JS encodeURIComponent%20%2F~'No
JS encodeURI%20/~'Yes
JS URLSearchParams+%2F%7E%27No
Python quote()%20/~%27No
Python quote_plus()+%2F~%27No
PHP rawurlencode()%20%2F~%27No
PHP urlencode() / our tool+%2F%7E%27No

Two of these catch people out. encodeURI is meant for a whole URL, so it leaves &, #, ?, = and + alone; used on a value, Café & Bar #1 becomes Caf%C3%A9%20&%20Bar%20#1, and the link breaks at the & and the #. Python's quote() keeps / by default, so a redirect target like /cart?id=7 keeps its slash unless you pass safe=''. For a single value, reach for encodeURIComponent, quote(value, safe='') or rawurlencode.

Worked example: passing a URL inside a URL

A login page needs to send people back to /cart?id=7 afterwards. If you write /login?next=/cart?id=7, the second ? and any later & confuse the parser. Encode the inner URL first:

/login?next=%2Fcart%3Fid%3D7

To check a finished link, we pasted https://shop.example/search?q=caf%C3%A9+%26+bar&next=%2Fcart%3Fid%3D7 into the URL parser. It showed the raw query and then the decoded parameters exactly as a server receives them:

{ "q": "café & bar", "next": "/cart?id=7" }

Two clean values, no stray parameters. Campaign links work the same way: every UTM value is a query parameter, so encode it, or better, keep it to lowercase words and underscores as our UTM parameters guide recommends.

Common URL encoding mistakes

Encoding the whole URL

Encoding https://mybotsy.com/?q=red shoes gives https%3A%2F%2Fmybotsy.com%2F%3Fq%3Dred+shoes, which is no longer a working link. That's only right when the entire URL is itself a parameter value, as in the redirect example above.

Encoding twice

Running already-encoded text through again encodes the percent signs. We tested a%20b and got a%2520b. If you see %25 followed by two hex digits in a link, it was double encoded. Decoding %25252F takes three passes to reach / (%252F, then %2F, then /).

Decoding a plus that was meant to stay

Form-style decoders, including our URL decoder, turn + into a space. We decoded q=mac+cheese&phone=%2B54+11+5555&path=%2Fdocs%2520v2 and got q=mac cheese&phone=+54 11 5555&path=/docs%20v2. The phone number survived only because its plus was written as %2B. A raw +54 would have come out as a space. The same thing corrupts Base64 values in URLs; see how to decode Base64 for the URL-safe alphabet that avoids it.

Mixing old Latin-1 escapes with UTF-8

Some old systems encode é as %E9 (one Latin-1 byte) instead of %C3%A9. Decoded as UTF-8, caf%E9 shows up as caf�. If you see the replacement character, the source used a legacy encoding.

Relying on silent trimming

Our encoder trims spaces at the very start and end of the input: " hello world" + line break + "line 2 " came out as hello+world%0D%0Aline+2. That's usually what you want, but if a leading space is meaningful, add %20 back by hand. Note that a line break typed in a browser becomes %0D%0A.

A lone % in JavaScript

JavaScript's decodeURIComponent("50%") throws URIError: URI malformed. Our decoder simply leaves a lone % as it is (50% off stays 50% off), which is handy for messy data but means it won't warn you either.

All of them are free and need no account. Visitors get 5 tool uses a day, and a free My Botsy account (100% free, no spam) removes that cap.

Frequently asked questions

What is URL encoding?

URL encoding, or percent-encoding, replaces characters that aren't allowed or have a special meaning in a URL with a % sign and the two-digit hex value of each byte. A space becomes %20, & becomes %26 and é becomes %C3%A9, its two UTF-8 bytes.

Should a space be %20 or + in a URL?

Inside a query string both work, because + is the form-style way to write a space there. In a path or a mailto link, use %20, since a + is read as a literal plus sign. Our URL encoder outputs +, so replace it with %20 for paths.

Which characters don't need to be encoded?

Only letters A to Z and a to z, digits 0 to 9 and the four symbols - . _ ~ are always safe. Reserved characters such as & ? # = / + : must be encoded when they are part of your data, and everything else (spaces, quotes, accents, emoji) is always encoded.

What is the difference between encodeURI and encodeURIComponent?

encodeURI is for a complete URL and leaves structural characters like & # ? = and / untouched. encodeURIComponent is for a single value and encodes them. Using encodeURI on a search term or redirect target breaks the link at the first & or #.

It was encoded twice. The first pass turned a space into %20, and the second turned the % into %25. Decode it once and encode the original text a single time.

Is the URL encoder free?

Yes. The My Botsy URL encoder is free, needs no account and works in any browser. Visitors get 5 tool uses a day, and a free account removes the cap.

Have a value to put in a link? Paste it into the free URL encoder, copy the result, and check the finished link with the URL parser.

How to Read a User Agent String (With Real Examples)

2 November, 2026

Learn to read any user agent string: which tokens matter, which values browsers freeze on purpose, and how to verify bots. Real parser resul..

How to Minify CSS (and How Much It Really Saves)

31 October, 2026

Minify CSS in seconds with a free tool, see the real savings after gzip and Brotli, and avoid the mistakes that silently break styles. Real ..

How to Decode Base64 (Text, Images and JWTs) Free

30 October, 2026

Decode any Base64 string in seconds: real examples for text, images, JWTs and Basic Auth, plus why output turns to gibberish and how to fix ..