decodeURIComponent()
Decodes every percent-escape in a string back to the characters it represents.
decodeURIComponent(encodedURI)- Added in JavaScript ECMAScript 3 (1999)
Parameters
| Parameter | Type | Description |
|---|---|---|
$encodedURI | string | An encoded component of a Uniform Resource Identifier. Other values are converted to strings. |
Return value
stringA new string with all percent-escape sequences decoded as UTF-8.
Errors
Throws URIError if a % is not followed by two hexadecimal digits, or if the escape sequence does not encode a valid UTF-8 character.
decodeURIComponent() is the inverse of encodeURIComponent(), and it decodes every escape it finds — including %2F, %3F and %26, which decodeURI() deliberately leaves alone. That makes it the right function for reading a single query value or path segment back out, and the wrong function for a whole URL, where decoding the delimiters changes the URL's structure.
It throws, so wrap it
Any input you did not encode yourself can be malformed. A trailing %, a stray %zz, or a truncated multi-byte sequence such as %E0%A4%A all raise a URIError. User-editable URLs, pasted links and log lines are exactly the inputs that break this, so put the call in a try block and decide what a bad value means.
Not a form decoder
It does not turn + into a space. Query strings produced by HTML forms use application/x-www-form-urlencoded, where + means space — use URLSearchParams for those, since it applies both rules. And decoding is not sanitising: a decoded value can contain quotes, angle brackets or newlines, so escape it again for whatever context it lands in.
Example
When to use it
- Read a query-string value out of a URL you parsed by hand.
- Recover a filename or title from an encoded path segment.
- Decode a redirect target that was carried as a percent-encoded parameter.
Frequently asked questions
Why do I get 'URIError: malformed URI sequence'?
Because the string contains a % that is not followed by two hex digits, or an incomplete UTF-8 escape sequence. Common causes are a literal percent sign in the data, a truncated URL, or decoding a value that was already decoded once.
Why does decodeURIComponent leave + signs alone?
Because + only means space in application/x-www-form-urlencoded data, not in URI percent-encoding. Use URLSearchParams to parse a query string, since it applies both the + rule and percent decoding.
Can I use decodeURIComponent on a full URL?
No — it decodes the reserved delimiters as well, so an encoded %2F or %3F inside a segment turns into a real slash or question mark and changes the URL's structure. Use decodeURI for a complete URL and decodeURIComponent for its individual parts.
More examples
Decoding safely
Three of these four inputs would throw URIError. The wrapper returns the raw string instead, which is usually better than losing the whole request over one bad character.
function safeDecode(s) {
try {
return decodeURIComponent(s);
} catch {
return s; // keep the raw value rather than crashing
}
}
console.log(safeDecode("caf%C3%A9")); // café
console.log(safeDecode("100%")); // 100%
console.log(safeDecode("%E0%A4%A")); // %E0%A4%A — truncated UTF-8
console.log(safeDecode("%zz")); // %zzdecodeURIComponent versus decodeURI
decodeURI decodes only %20, leaving %2F, %3F and %3D encoded so the URL keeps its shape. decodeURIComponent decodes all of them, turning what was one path segment into a path plus a query — which is why it must not be used on a full URL.
const s = "https://example.com/a%2Fb%3Fq%3D1%20x";
console.log(decodeURI(s));
console.log(decodeURIComponent(s));Query strings and the plus sign
URLSearchParams prints "cats and dogs" and "50%" because it applies form decoding, where + means space. The manual call leaves the plus signs in place, which is the correct behaviour for this function but the wrong result for a form-encoded query.
const qs = "q=cats+and+dogs¬e=50%25";
for (const [k, v] of new URLSearchParams(qs)) {
console.log(k, "=>", v);
}
// Doing it by hand misses the + rule
console.log(decodeURIComponent("cats+and+dogs"));
Discussion