decodeURIComponent()
The inverse of encodeURIComponent. Its one hard edge is that malformed input throws rather than degrading, which matters because the input usually comes from a URL you did not write.
Demo
The pair is [decodeURIComponent, decodeURI]. The second case shows the asymmetry that mirrors the encode side: %26 becomes & under decodeURIComponent and stays %26 under decodeURI, because decodeURI deliberately refuses to decode anything that would change a URL structure. The fourth case catches people constantly — a + stays a plus sign, because the plus-means-space convention belongs to form encoding, not to URLs. The last case throws: a lone % is malformed, and there is no lenient mode.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| string | string | yes | The percent-encoded text. decodeURI leaves reserved sequences such as %26 and %2F encoded; decodeURIComponent decodes everything. |
Return value
string — The decoded string. Throws URIError for a malformed sequence — a % not followed by two hex digits, or bytes that are not valid UTF-8.
Common patterns
const q = new URL(href).searchParams.get('q');
let v; try { v = decodeURIComponent(raw); } catch { v = raw; }
decodeURIComponent(raw.replace(/\+/g, ' '));
Examples
Pitfalls
decodeURIComponent('100%')
try { decodeURIComponent(raw); } catch { /* use raw */ }
decodeURIComponent('hello+world')
new URLSearchParams('q=hello+world').get('q')
decodeURIComponent(decodeURIComponent('%252F'))
decodeURIComponent('%252F')
decodeURI(encodeURIComponent('a&b'))
decodeURIComponent(encodeURIComponent('a&b'))
When to use
- Decoding one value you escaped with encodeURIComponent
- Reading a percent-encoded path segment
- Tidying a display string that arrived encoded
- Reading query strings → URLSearchParams, which handles +
- The input may be malformed → wrap it in try/catch
- A whole URL → decodeURI, or leave it encoded
- unescape() → deprecated and wrong for UTF-8
Notes
FAQ
Because % begins an escape sequence, so a % not followed by two hex digits is malformed input and the specification requires a URIError. There is no lenient mode — wrap it, or validate first.
const safe = s => { try { return decodeURIComponent(s); } catch { return s; } };