Secrets and encoding

Why a plus sign becomes a space in a URL query

A + becomes a space when a query is parsed using form-encoding rules. A literal plus must be encoded as %2B. PageUtil’s URL Encoder uses encodeURIComponent and decodeURIComponent, so its component decoder leaves a raw + unchanged.

URL component encoding, HTML escaping and Base64 solve different representation problems.
Choose the encoding for the boundary you are crossing; decoding rules are not interchangeable.

Observe two different decoding contracts

Consider the value C++ primer. Constructing a query by concatenating q=C++ primer produces raw plus signs that a form parser treats as spaces. The encoded value C%2B%2B+primer preserves the two literal plus signs and uses + for the separating space.

The same raw string can therefore produce different results in a component decoder and a form query parser. Neither operation is necessarily broken: they implement different contracts. Check where the value is encoded and where it is decoded.

new URLSearchParams("q=C++").get("q"); // "C  "
decodeURIComponent("C++");             // "C++"

const params = new URLSearchParams();
params.set("q", "C++ primer");
params.toString(); // "q=C%2B%2B+primer"
params.get("q"); // "C++ primer"

Encode the raw value once at the query boundary

Use URLSearchParams.set or append with an unencoded value. If you pass C%2B%2B as the raw value, the percent signs themselves get encoded, producing C%252B%252B. One decoding pass then returns percent sequences instead of plus signs.

When building a query manually, encode each value rather than the entire URL. Encoding the complete address as one component also encodes delimiters such as :, /, ? and &, changing the structure.

Do not repair all plus signs by replacing them with spaces indiscriminately. In a path component, signed URL, Base64 data or application-specific string, a literal plus may be meaningful. Apply the rules documented for that field.

What crosses the boundary
Intended raw valueQuery representationDecoded value
C++q=C%2B%2BC++
a bq=a+ba b
a+bq=a%2Bba+b
Literal text %2Bq=%252B%2B

Find the first boundary where the value changes

Inspect the client’s raw value, the actual request URL and the server’s parsed parameter. Use a synthetic test value such as a+b c rather than a real token. It makes plus, space and percent handling visible in one small example.

Use URL Encoder for a single component, then check the actual application’s form parsing separately. Repeatedly decoding until a string looks right can break intended literal percent sequences and introduce security problems. Fix the producer/consumer agreement instead.

References

Use the linked specifications and product documentation to check behavior in your own environment.

Continue troubleshooting

Related tools

Frequently asked questions

Does PageUtil convert plus to space?

No. Its component decoder leaves raw plus signs intact and decodes percent sequences.

What encodes a literal plus in a query?

Use %2B for a literal plus when the query uses form-encoding rules.

Why does my URL contain %252B?

The percent sign in an already encoded %2B was encoded again.

Need help with a tool or found a bug?

Report an issue directly to engineering. No accounts required — all client data remains private on your device.

Report an Issue →