Guide

Spaces in URLs: %20 vs +

Learn when a space becomes %20 or +, how to preserve a literal plus sign, and which encoding belongs to each context.

by Tools in a Tab · Published on · Updated

Short answer

%20 represents a space through percent-encoding in a URL. A plus sign represents a space specifically in application/x-www-form-urlencoded data, which is often used for queries and forms. Outside that format, + can be a literal plus sign. To preserve it in form data, encode it as %2B.

Three inputs with different meanings

Suppose you need to transport these values:

Original value Percent-encoded component URL-encoded form
black coffee black%20coffee black+coffee
a+b a%2Bb a%2Bb
a b a%20b a+b

The ambiguity appears when a+b is decoded under form rules: the output is a b, not the original plus sign. A + that belongs to the data must therefore arrive as %2B in that context.

Which rule each API uses

encodeURIComponent("a b") returns a%20b. By contrast, URLSearchParams serializes the space as + because it uses form encoding. Both outputs can be correct; they implement different algorithms for different contexts.

The percent-encoding section of RFC 3986 defines the %HH form. The WHATWG URL Standard defines the application/x-www-form-urlencoded algorithm that turns a space into +.

What the tool does

Tools in a Tab’s URL encoder and decoder offers three explicit modes. Choose the mode before encoding or decoding:

Mode Encode a b Decode a+b
Component a%20b a+b
Complete URL or path a%20b a+b
Form / query value a+b a b

The complete-URL mode preserves structural delimiters; use component mode for one segment or value. Form mode handles one value, not an entire form body. To build several parameters, use the query string parser, which keeps names, values, and repeated occurrences separate.

Preserve a literal plus with URLSearchParams

Pass the unencoded value to set instead of interpolating it into a query:

const params = new URLSearchParams();
params.set('q', 'a+b c');
params.toString(); // 'q=a%2Bb+c'
params.get('q'); // 'a+b c'

By contrast, new URLSearchParams('q=a+b').get('q') returns a b: the string constructor parses form-encoded data. Do not pre-encode the value passed to set; an existing %2B would become %252B. See MDN’s URLSearchParams examples.

Practical rule

  1. Identify whether you are encoding a URL component or form data.
  2. For components, expect %20 for a space.
  3. For URL-encoded form data, expect + for a space.
  4. Encode a literal plus as %2B whenever the receiver applies form rules.

Do not replace every + with a space without knowing the format. That shortcut can change valid data.