%20 or + for a Space?

When each is right, and why mixing them breaks things.

The Short Answer

%20 is always correct. A + means a space only in the query string (after the ?) and in form data. Anywhere else in a URL, + is just a plus sign.

Most bugs come from mixing the two: text encoded with one rule and decoded with the other.

Encode text with %20 →

Where Each One Is Valid

Part of the URLSpace as %20Space as +
Path — /files/my%20doc.pdfYesNo — + is a literal plus
Query string — ?q=hello+worldYesYes, by convention
Form body (application/x-www-form-urlencoded)YesYes — the form default
Fragment — #section%20twoYesNo

So /search/hello+world means a page called hello+world, while ?q=hello+world usually means the search hello world.

Where the + Comes From

The general URL standard encodes a space as %20, like any other character that needs escaping. The + comes from HTML forms: when a browser submits a form, it encodes spaces in the field values as +. Servers learned to decode + as a space in form data and query strings, and the habit spread to query strings generally.

That's why it works only there. It's a form-encoding rule, not a URL rule.

What Each Language Produces

LanguageSpace → %20Space → +
JavaScriptencodeURIComponentURLSearchParams
Pythonurllib.parse.quotequote_plus, urlencode
PHPrawurlencodeurlencode
Javajava.net.URI (multi-argument constructor)URLEncoder.encode

The trap is decoding with the other family. In JavaScript, decodeURIComponent("hello+world") returns hello+world, while URLSearchParams reads the same text as hello world. Neither is wrong; they apply different rules.

The Classic Bug: A Real Plus Sign

Because + means a space in form data, a literal plus has to be encoded as %2B. Forget, and a server decodes it as a space. That's why a phone number like +44 20 arrives with a space where the plus was, and email addresses such as [email protected] end up as name [email protected].

Encoding the value with a %20-style encoder avoids this, since those encode + as %2B automatically.

Using the Tools Here

The URL Encoder encodes a space as %20 and a plus as %2B, so its output is safe anywhere in a URL.

The URL Decoder follows the general URL rule, where + is a literal plus. If you're decoding a query string or form data where + stands for a space, replace each + with a space first, then decode. Both run in your browser, so tokens or internal URLs you paste in aren't sent anywhere.

Frequently Asked Questions

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

%20 is always correct. + is an older convention that means a space only in query strings and form submissions. In the path part of a URL, + is a literal plus sign. If you are unsure, use %20.

Why does + mean a space at all?

It comes from HTML form encoding, where browsers submitting a form replace spaces with +. Servers decoding form data and query strings undo that, so + became a common shorthand in the part of a URL after the question mark. The general URL standard itself encodes a space as %20.

How do I put a real plus sign in a query string?

Encode it as %2B. Otherwise a server reading form-encoded data will decode it as a space, which is why phone numbers like +1 555 and email addresses with + in them often arrive broken.

Why does my JavaScript produce %20 in one place and + in another?

Because the two built-in methods follow different rules. encodeURIComponent encodes a space as %20. URLSearchParams follows form encoding and writes +. Both decode their own output correctly, but decodeURIComponent does not turn + into a space.

Does the URL decoder on this site turn + into a space?

No. It follows the general URL rule, where + is a literal plus, so hello+world stays hello+world. If you are decoding a query string or form data where + stands for a space, replace + with a space first, then decode.