When does a URL use %20 or a plus sign?

Use %20 for a space in a URL component; a plus sign means a space in form-style query data.

They look like two spellings for the same thing, but the right one depends on how the value will be read.

Why do spaces become %20 or +?

A space is %20 in a URL component. In form-style query data, it can be +. Think of two address-label systems: both carry your text, but you need a reader that knows the spelling rules. A component is one piece of a URL, such as a search value; form-style query data packages names and values together.

Take the value a b+c. The space gets a different spelling in each format; the literal plus becomes %2B in both.

Original a b+c branches into component output a%20b%2Bc and form-style query q=a+b%2Bc. Teal marks the original space; gold marks the original plus.
Teal follows the space; gold follows the literal plus. A matching component decoder or query reader recovers the original value. Sources and method notes

Form-style encoding is called application/x-www-form-urlencoded. URLSearchParams, JavaScript's helper for building and reading query pairs, uses those rules. A plus isn't a universal spelling for a space everywhere in a URL.

Why encode a search value before adding it to a link?

A URL is an address label with dividers. A question mark opens the query, an ampersand separates its name-and-value pairs, and a hash starts a fragment, such as a place within a page. Encoding keeps punctuation in your text from being mistaken for those dividers.

Suppose your search phrase is R&D = #1. Adding it raw after q= splits the phrase; encoding the value keeps it together.

Raw R&D = #1 splits into q equal to R, an extra query pair, and fragment #1. Encoded R%26D%20%3D%20%231 gives one q value R&D = #1 and an empty fragment.
Both links start with the same address. The parsed values underneath show what the receiving query reader gets.

Which part of a link should you encode?

For a hand-built link, encode the original value once. Leave the address and its dividers outside the component encoder.

Three steps: isolate R&D = #1 after q=, encode it as R%26D%20%3D%20%231, and put it back after https://example.test/search?q=.
A component encoder also escapes slashes and question marks, so a complete address doesn't belong in its input.

An already encoded value isn't the same input as the original text. Encoding it again turns its percent signs into %25.

red fox becomes red%20fox after encoding once. A second encoding produces red%2520fox because the percent sign becomes %25.
Use the original value at the encoding step; don't feed the encoded result back into that step.

If you're writing JavaScript to build query pairs, URLSearchParams can handle the encoding for you.

Give URLSearchParams the original name q and value a b+c, set the pair, and serialize it as q=a+b%2Bc.
The name and value start as decoded text. params.set adds the pair; params.toString() produces the query text shown here.

How do you decode spaces and literal plus signs?

Match the reader to the format that produced the text. A component decoder preserves a literal +; a form-style query reader turns it into a space.

Component decoding a+b%2Bc returns a+b+c. Reading q=a+b%2Bc with URLSearchParams returns the q value a b+c.
Both readers decode %2B as a literal plus. They disagree about the unescaped +.

Component decoding with decodeURIComponent(), including FluffyBench's component decoder, rejects broken percent escapes and bytes that aren't valid UTF-8. Query-pair parsing through URLSearchParams is forgiving: malformed escapes can remain as text, and invalid UTF-8 can become replacement characters. A query that parses isn't proof that the original text arrived intact.

Doing it in FluffyBench's URL Encoder

FluffyBench's URL Encoder encodes and decodes one component locally. Its component operations don't build form-style query pairs. Short inputs update automatically, so these examples don't need a run-button click.

To make one value ready for a link, use Component → URL-encoded.

  1. FluffyBench From and To controls set to Component and URL-encoded.
    FluffyBench From and To controls set to Component and URL-encoded.
    Step 1. Choose From: Component and To: URL-encoded.
    1. From: Component, the one value you have.
    2. To: URL-encoded, the link-safe spelling.
  2. Phone Input view with a b+c and the Input and Result tabs.
    Phone Input view with a b+c and the Input and Result tabs.
    Step 2. Paste only the value, here a b+c. The result updates as you type.
    1. Paste the value: a b+c.
    2. Open Result on a phone.
  3. FluffyBench result a%20b%2Bc under the URL-encoded label.
    FluffyBench result a%20b%2Bc under the URL-encoded label.
    Step 3. Spaces became %20 and the plus sign became %2B.
    1. URL-encoded and the character count.
    2. Check the result: a%20b%2Bc.
  4. FluffyBench Copy and Download buttons, shown close up.
    FluffyBench Copy and Download buttons, shown close up.
    Step 4. Take the result to another app with Copy, or save it with Download.
    1. Copy puts the result on your clipboard.
    2. Download saves a text file.

To recover one encoded value, use URL-encoded → Component. Copy and Download work the same way in either direction.

  1. FluffyBench From and To controls set to URL-encoded and Component.
    FluffyBench From and To controls set to URL-encoded and Component.
    Step 1. Choose From: URL-encoded and To: Component.
    1. From: URL-encoded, the text with percent codes.
    2. To: Component, the readable value.
  2. Phone Input view with a%20b%2Bc and the Input and Result tabs.
    Phone Input view with a%20b%2Bc and the Input and Result tabs.
    Step 2. Paste the encoded text, here a%20b%2Bc.
    1. Paste the encoded text: a%20b%2Bc.
    2. Open Result on a phone.
  3. FluffyBench result a b+c under the Component label.
    FluffyBench result a b+c under the Component label.
    Step 3. The component decoder recovers a b+c.
    1. Component and the character count.
    2. Check the result: a b+c.

Use FluffyBench's URL Encoder to encode or decode one value

What does a percent escape represent?

A percent sign followed by 2 hexadecimal digits represents one byte. Hexadecimal is a compact spelling for a byte's value. UTF-8 turns text into bytes before those bytes are escaped.

A space needs one escape. The letter é becomes C3 A9 in UTF-8, so it needs an escape for each byte.

Space maps to UTF-8 byte 20 and escape %20. The letter é maps to bytes C3 and A9 and escapes %C3 and %A9.
Each colored byte maps to its own percent escape. One visible character can take several escapes.
Search FluffyBench