URL Encoding Characters: What to Encode and Where
The same character can be fine in one part of a URL and break another. Here is a reference table of what each JavaScript and Python function does with the characters that matter.
URL encoding characters correctly depends on where in the URL they go: a / is fine in a path, an & is fine in a fragment, and both break a query value. The URL Encoder encodes text in the browser, and its page explains why encodeURI and encodeURIComponent do different jobs. This guide is a reference: what each function does with each character, and which one to use for each part.
URL encoding characters: a reference table
Output of each JavaScript function, run in Node:
Char encodeURIComponent encodeURI URLSearchParams
space %20 %20 +
+ %2B + %2B
/ %2F / %2F
? %3F ? %3F
# %23 # %23
& %26 & %26
= %3D = %3D
% %25 %25 %25
@ %40 @ %40
: %3A : %3A
é %C3%A9 %C3%A9 %C3%A9
~ ~ ~ %7E
' ' ' %27
( ( ( %28Non-ASCII characters are always encoded as their UTF-8 bytes, so é becomes two escapes. Note the rows where the functions disagree: encodeURI leaves +, /, ?, #, & and = alone because they have meaning in a full URL, and URLSearchParams writes a space as + and also escapes ~, ' and (.
Which function for which part of a URL
- A path segment, such as a product name in
/products/{name}:encodeURIComponent. It encodes/, so a name containing a slash cannot add a path level. - A query parameter value:
URLSearchParams, orencodeURIComponentif you build the string yourself. Both encode&,=and#, which would otherwise end the value early. - A whole URL that is already assembled:
encodeURI, which only fixes characters that can never appear raw, such as spaces and non-ASCII letters. Never run it on a URL that contains user data in its query. - A fragment:
encodeURIComponentis the safe default.
const url = new URL("https://shop.example.com/search");
url.searchParams.set("q", "socks & shoes");
url.searchParams.set("next", "/cart?step=2");
url.toString();
// "https://shop.example.com/search?q=socks+%26+shoes&next=%2Fcart%3Fstep%3D2"Building URLs through the URL object is the least error-prone option: you set raw values and it encodes them for the right part.
URL encoding in Python
from urllib.parse import quote, quote_plus, urlencode
quote("a/b c") # 'a/b%20c' keeps / by default
quote("a/b c", safe="") # 'a%2Fb%20c' for a path segment
quote_plus("socks & shoes") # 'socks+%26+shoes'
urlencode({"q": "SAVE 10", "next": "/cart?a=1"})
# 'q=SAVE+10&next=%2Fcart%3Fa%3D1'quote leaves / unencoded unless you pass safe="", a common source of broken path segments. quote_plus and urlencode use + for spaces, matching what HTML forms send, while quote uses %20.
Related tools
Related guides
Tracking links and login redirects nest one URL inside another, encoded once per layer. Here is how to unwrap them correctly in JavaScript and Python, and the redirect check that keeps it safe.
Base64 turns bytes into plain text so they can travel where only text is allowed. Here are the five places developers meet it most, with real examples, and the cases where it is the wrong tool.
Two formatters can disagree about the same JSON file. Here is how a team picks one, applies it in every editor and before every commit, and makes CI enforce it.