Why URLs need percent-encoding
A URL can only safely contain a limited set of characters — letters, digits, and a handful of punctuation marks that have no special meaning in that position. Everything else (spaces, ampersands inside a value, non-English characters, slashes inside a value rather than as a path separator) has to be percent-encoded: replaced with % followed by its byte value in hex. A space becomes %20, an ampersand becomes %26, and so on.
Get this wrong and a URL either breaks outright or, worse, silently does the wrong thing — an unencoded &inside a query value looks like the start of the next parameter, quietly truncating or corrupting the one before it.
Example
Encoding hello world & more/less? as a single value gives:
hello%20world%20%26%20more%2Fless%3FEvery character outside letters, digits and -_.~ is escaped, including the slash and question mark, since as a value they carry no special meaning.
Component vs. full-URL encoding
The common mistake is running an entire URL through component-style encoding, which escapes the very characters (:, /, ?, &, =) that make it a URL in the first place. The rule of thumb: encode a value that will be placed inside a URL with the component option; only use the full-URL option on something that is already a complete, structurally valid URL and only needs its non-ASCII or space characters escaped.
Doing it in code
JavaScript
encodeURIComponent("hello world & more"); // "hello%20world%20%26%20more"
encodeURI("https://x.y/p q?a=b c"); // "https://x.y/p%20q?a=b%20c"
decodeURIComponent("hello%20world"); // "hello world"Python
from urllib.parse import quote, unquote, quote_plus
quote("hello world & more") # 'hello%20world%20%26%20more'
quote_plus("hello world") # 'hello+world'
unquote("hello%20world") # 'hello world'