A search value is café & tea. You append it to a URL and encode the whole result. The server receives a second parameter instead of one search value. The ampersand was data inside the value, but the URL parser treated it as a separator.
Run both encoding boundaries
Open URL Workbench. Choose Encode component and paste the exact value below.
Input: café & tea
Expected: caf%C3%A9%20%26%20tea
Now choose Encode whole URL and use the same input. The expected output is different:
caf%C3%A9%20&%20tea
Whole-URL encoding preserves reserved delimiters, including &, because they may structure a complete URL. Component encoding escapes that ampersand so it remains part of a value. Encode at the boundary where you know the meaning of the text.
Inspect repeated keys without collapsing them
Choose Parse URL & query and enter this URL. Nothing is fetched; parsing happens in the browser.
https://api.example.test/search?tag=json&tag=url&q=hello+world
The decoded query view contains three rows, in order:
tag json
tag url
q hello world
Turning those rows into a plain object would require a policy for repeated keys. Diggwigs keeps the rows instead of silently choosing the first or last value.
A plus sign depends on the decoding rule
Query parsing uses form-style decoding, where + means a space. Decode component uses decodeURIComponent semantics, where + stays literal.
Operation: Decode component
Input: hello+world
Expected: hello+world
Input: %E0%A4%A
Expected: malformed encoding error; original input retained
Decode whole URL also preserves encoded reserved delimiters such as %26. Decoding a value twice can turn an encoded separator into active URL structure. Keep track of whether each value is raw, encoded, or parsed, and decode once at its defined boundary.
Build the structure with URL APIs. Encode the value at the point where it joins that structure.