ESC

Type to search the knowledge base.

URL and URLSearchParams

Parse and build URLs safely with the URL API — search params, base resolution, encoding, and common SPA routing helpers.

beginner3 min read
  • javascript
  • url-and

String-splitting query strings breaks on encoding edge cases. The URL and URLSearchParams APIs parse and serialize correctly — use them for links, fetch targets, and router glue.

const url = new URL('https://example.com:443/path?q=a%20b#hash');
url.protocol; // 'https:'
url.hostname; // 'example.com'
url.port;     // '' (default port omitted)
url.pathname; // '/path'
url.search;   // '?q=a%20b'
url.hash;     // '#hash'
url.origin;   // 'https://example.com'

Relative resolution

const abs = new URL('/api/users', 'https://example.com/app/');
// https://example.com/api/users

const abs2 = new URL('users', 'https://example.com/app/');
// https://example.com/app/users

new URL(input) without base throws if input isn’t absolute. Handy for validating user-entered absolute URLs:

function isAbsoluteHttpUrl(s) {
  try {
    const u = new URL(s);
    return u.protocol === 'http:' || u.protocol === 'https:';
  } catch {
    return false;
  }
}

Search params

const url = new URL('https://example.com/search?q=react&page=1');
url.searchParams.get('q'); // 'react'
url.searchParams.getAll('tag'); // multi
url.searchParams.set('page', '2');
url.searchParams.append('tag', 'js');
url.searchParams.delete('tag');
url.searchParams.has('q'); // true

url.toString(); // encoded properly
// Build from scratch
const params = new URLSearchParams({ q: 'a b', page: '1' });
params.toString(); // 'q=a+b&page=1' (application/x-www-form-urlencoded style)
fetch(`/api?${params}`);

Iterate:

for (const [k, v] of url.searchParams) {
  console.log(k, v);
}

Encoding footguns

// Manual — easy to get wrong
// '?' + 'q=' + encodeURIComponent(q)

// URLSearchParams encodes values; note space → + in query form
// Path encoding is different — set pathname carefully
url.pathname = '/a b'; // browser normalizes/encodes

Don’t put raw unescaped user input into path segments without encoding (encodeURIComponent per segment).

SPA helpers

function updateQuery(patch) {
  const url = new URL(window.location.href);
  for (const [k, v] of Object.entries(patch)) {
    if (v == null) url.searchParams.delete(k);
    else url.searchParams.set(k, String(v));
  }
  window.history.replaceState(null, '', url);
}

Works with the History API for shareable filter state.

vs location properties

location.search is a string; parsing by hand is obsolete. document.URL is a string snapshot — prefer new URL(location.href).

Interview answer (out loud)

“I use the URL constructor with an optional base for resolution and validation. URLSearchParams handles get/set/append and correct encoding for query strings. I avoid manual split/join for queries and use history.replaceState with URL when syncing SPA filters.”

Auth and open redirects

function safeRedirect(next) {
  const u = new URL(next, window.location.origin);
  if (u.origin !== window.location.origin) {
    return '/'; // reject open redirect
  }
  return u.pathname + u.search + u.hash;
}

Never trust a ?next= query as a free navigation target without origin checks.

Sorting and stable serialization

function stableQuery(params) {
  const sp = new URLSearchParams(params);
  const entries = [...sp.entries()].sort(([a], [b]) => a.localeCompare(b));
  return new URLSearchParams(entries).toString();
}

Useful for cache keys so a=1&b=2 and b=2&a=1 hit the same entry when order shouldn’t matter.

const url = new URL(location.href);
url.hash;   // client-only; not sent to server on request
url.search; // sent on navigation/fetch to that URL

SPAs sometimes store UI state in the hash; prefer search for shareable filters that SSR or analytics should see — product decision.

file: and blob: URLs

const u = new URL('blob:https://example.com/uuid');
// still parseable; be careful comparing origins with blob:

Object URLs from URL.createObjectURL need revokeObjectURL — different topic, same URL namespace.

Further reading

Related guides