Extracting Data from URLs in JavaScript: Practical Guide

May 28, 20266 min read

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.

FunctionEncodes ?, &, =Use For
encodeURINoFull URLs
encodeURIComponentYesParameter 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 URL constructor for parsing — avoid regex and string splitting
  • URLSearchParams handles query string parsing, iteration, and modification
  • Always use encodeURIComponent for parameter values, never encodeURI
  • 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

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.