Extracting Data from URLs in JavaScript: Practical Guide
Why Parse URLs in JavaScript?
Nearly every web application works with URLs — reading query parameters, navigating between routes, or constructing API endpoints. JavaScript provides powerful built-in APIs that make URL parsing straightforward, yet many developers still reach for string manipulation tricks that break on edge cases.
Using the right API prevents bugs with encoded characters, missing protocols, and unexpected URL structures.
The URL Constructor
The URL constructor is your primary tool for parsing URLs in JavaScript:
const url = new URL('https://example.com/tools/url-parser?format=json&page=2#results')
url.protocol // 'https:'
url.hostname // 'example.com'
url.port // '' (empty for default ports)
url.pathname // '/tools/url-parser'
url.search // '?format=json&page=2'
url.hash // '#results'
url.origin // 'https://example.com'
url.href // Full URL string
If the URL is relative, provide a base:
const url = new URL('/api/users?q=test', 'https://example.com')
url.hostname // 'example.com'
url.pathname // '/api/users'
Working with Query Parameters
The URLSearchParams API handles query string parsing:
const params = new URLSearchParams('?format=json&page=2&sort=name')
params.get('format') // 'json'
params.get('page') // '2'
params.get(' nonexistent') // null
params.has('sort') // true
params.getAll('tag') // ['js', 'tools'] (for ?tag=js&tag=tools)
Accessing params from a URL object
const url = new URL('https://example.com/search?q=hello&lang=en')
url.searchParams.get('q') // 'hello'
url.searchParams.get('lang') // 'en'
Iterating over all parameters
for (const [key, value] of url.searchParams) {
console.log(`${key}: ${value}`)
}
Modifying parameters
const url = new URL('https://example.com/search')
url.searchParams.set('q', 'hello')
url.searchParams.append('filter', 'active')
url.searchParams.delete('page')
url.toString() // 'https://example.com/search?q=hello&filter=active'
Parsing Path Segments
The pathname property gives you the full path. Split it to work with individual segments:
const url = new URL('https://example.com/tools/url-parser/guide')
const segments = url.pathname.split('/').filter(Boolean)
// ['tools', 'url-parser', 'guide']
Filter out empty strings to handle leading and trailing slashes cleanly.
Extracting dynamic route parameters
// Given pattern /users/:id/posts/:postId
function extractParams(pattern, pathname) {
const patternParts = pattern.split('/')
const pathParts = pathname.split('/')
const params = {}
for (let i = 0; i < patternParts.length; i++) {
if (patternParts[i].startsWith(':')) {
params[patternParts[i].slice(1)] = pathParts[i]
}
}
return params
}
extractParams('/users/:id/posts/:postId', '/users/42/posts/7')
// { id: '42', postId: '7' }
Handling Hash Fragments
const url = new URL('https://example.com/docs#installation')
url.hash // '#installation'
// Without the # prefix
url.hash.slice(1) // 'installation'
Hash fragments are never sent to the server. Use them for client-side navigation, scroll anchoring, or storing lightweight client state.
URL Encoding and Decoding
URLs restrict characters to a safe ASCII subset. Other characters must be percent-encoded:
// Encode values for safe URL insertion
encodeURIComponent('hello world') // 'hello%20world'
encodeURIComponent('price=10') // 'price%3D10'
// Decode values from URLs
decodeURIComponent('hello%20world') // 'hello world'
Critical: Use encodeURIComponent for individual parameter values — it encodes =, &, and ?. Never use encodeURI for parameter values, as it leaves those characters unencoded.
| Function | Encodes ?, &, = | Use For |
|---|---|---|
encodeURI | No | Full URLs |
encodeURIComponent | Yes | Parameter values |
Common Pitfalls
Missing protocol
// THROWS: Invalid URL
new URL('example.com/path')
// FIX: Add protocol
new URL('https://example.com/path')
// FIX: Use base parameter
new URL('example.com/path', 'https://example.com')
// Wait — this treats 'example.com/path' as a relative path
// Correct approach:
new URL('https://example.com/path')
Double encoding
// BAD: Encoding an already-encoded value
encodeURIComponent('hello%20world') // 'hello%2520world' — double encoded
// Decode first, then re-encode if needed
decodeURIComponent('hello%20world') // 'hello world'
Null vs empty string
const params = new URLSearchParams('?q=')
params.get('q') // '' (empty string, not null)
params.has('q') // true
const params2 = new URLSearchParams('?page')
params2.get('page') // '' (empty string)
Key Takeaways
- Use the
URLconstructor for parsing — avoid regex and string splitting URLSearchParamshandles query string parsing, iteration, and modification- Always use
encodeURIComponentfor parameter values, neverencodeURI - Provide a base URL when parsing relative URLs
- Watch for double encoding and missing protocol errors
searchParams.get()returns null for missing keys and empty string for empty values
Related Guides
Try It Yourself
Parse and inspect any URL interactively with our free URL Parser. Paste a URL and see every component — protocol, host, path, query, and hash — broken down instantly.