encodeURI()
Percent-encodes a complete URL while leaving the characters that give it structure intact.
encodeURI(uri)- Added in JavaScript ECMAScript 3 (1999)
Parameters
| Parameter | Type | Description |
|---|---|---|
$uri | string | A string to be encoded as a URI. Other values are converted to strings. |
Return value
stringA new string with characters outside the unreserved and reserved URI sets replaced by their UTF-8 percent-encoded form.
Errors
Throws URIError if the input contains a lone surrogate, which cannot be encoded as UTF-8.
encodeURI() is the light-touch encoder. It escapes spaces, quotes, angle brackets, non-ASCII characters and control characters, but leaves alone both the unreserved set (A–Z a–z 0–9 - _ . ! ~ * ' ( )) and the reserved delimiters ; / ? : @ & = + $ , #. That is what lets you hand it an entire URL and get a working URL back.
When to use it
Use it on a URL that is already assembled — typically one that came from user input, a document, or a database, and may contain spaces or accented characters. It cleans up a nearly-valid address without disturbing its syntax.
When not to use it
Do not use it on a value you are about to interpolate. Because it preserves & and =, a search term containing an ampersand will silently become a second query parameter. That case needs encodeURIComponent(). The rule of thumb: encodeURI() for the whole thing, encodeURIComponent() for each piece.
It is not validation
The output can still be a nonsense URL — the function only substitutes characters. It also leaves an existing % untouched, so encoding an already-encoded URL is a no-op on the escapes rather than a double-encoding, but a stray literal % in the input will produce a string that decodeURI() then refuses.
Example
When to use it
- Clean up a URL pasted by a user that contains spaces or accented characters.
- Prepare a link built from a filesystem path or document title for use as an href.
- Normalise a URL containing non-ASCII characters before logging or comparing it.
Frequently asked questions
When should I use encodeURI instead of encodeURIComponent?
Use encodeURI when you already have a complete URL and only need to escape unsafe characters such as spaces; use encodeURIComponent for any individual value you are inserting into a URL. encodeURI preserves ? & = / : #, which is helpful for a full URL and dangerous for a parameter.
Does encodeURI escape the ampersand?
No. & is a reserved delimiter and is left as-is, which is why a query value containing & must be passed through encodeURIComponent instead.
Is it safe to call encodeURI on an already-encoded URL?
Mostly, since % itself is not re-escaped, so existing %XX sequences pass through unchanged. But any literal percent sign in the original data will still be ambiguous afterwards, so encode once and track whether a string is encoded rather than calling it defensively.
More examples
The correct division of labour
The first line produces ?q=jazz%20&%20blues&tag=a/b — the ampersand inside the term now reads as a parameter separator. The second escapes it to %26 so the term stays one value.
const base = "https://example.com/search";
const term = "jazz & blues";
const tag = "a/b";
// Wrong: encodeURI leaves & alone, so term splits the query
console.log(encodeURI(`${base}?q=${term}&tag=${tag}`));
// Right: encode each value, assemble afterwards
console.log(`${base}?q=${encodeURIComponent(term)}&tag=${encodeURIComponent(tag)}`);Which characters each function keeps
encodeURI returns the reserved set unchanged; encodeURIComponent escapes every one of them. Both leave the nine unreserved marks as literal characters, which is why neither output is safe to feed to a server that treats ' or ( as reserved.
const specials = ";/?:@&=+$,#";
console.log("encodeURI :", encodeURI(specials));
console.log("encodeURIComponent :", encodeURIComponent(specials));
const unreserved = "-_.!~*'()";
console.log("both leave alone :", encodeURI(unreserved), encodeURIComponent(unreserved));Non-ASCII and round-tripping
Cyrillic characters become UTF-8 percent escapes and the space becomes %20, while the scheme and slashes survive. decodeURI reverses it exactly, and the URL constructor reaches the same result without manual encoding.
const u = "https://example.com/файлы/отчёт 2024.pdf";
const enc = encodeURI(u);
console.log(enc);
console.log(decodeURI(enc) === u); // true
// The URL constructor does the same normalisation for you
console.log(new URL(u).href === enc);
Discussion