You've already seen URL and URLSearchParams used in passing on the Query String page. This page looks at the URL module more completely — the pieces a URL breaks into, and how Node.js lets you read and build them.
Anatomy of a URL
https://user:pass@shop.example.com:8080/products/shoes?color=black&size=42#reviews
const { URL } = require('url');
const myUrl = new URL('https://user:pass@shop.example.com:8080/products/shoes?color=black&size=42#reviews');
console.log(myUrl.protocol); // 'https:'
console.log(myUrl.username); // 'user'
console.log(myUrl.password); // 'pass'
console.log(myUrl.hostname); // 'shop.example.com'
console.log(myUrl.port); // '8080'
console.log(myUrl.pathname); // '/products/shoes'
console.log(myUrl.search); // '?color=black&size=42'
console.log(myUrl.hash); // '#reviews'
console.log(myUrl.origin); // 'https://shop.example.com:8080'
console.log(myUrl.href); // the entire URL as a string
Each piece is its own property — no manual string-splitting or regular expressions needed to pull a URL apart.
Building a URL from pieces, rather than parsing one
const apiUrl = new URL('https://api.example.com');
apiUrl.pathname = '/v1/products';
apiUrl.searchParams.set('category', 'electronics');
apiUrl.searchParams.set('limit', '20');
console.log(apiUrl.href);
// https://api.example.com/v1/products?category=electronics&limit=20
Assigning to properties like pathname and using .searchParams.set() builds the URL incrementally and correctly, handling any characters that need escaping automatically.
Resolving a relative URL against a base
const base = 'https://shop.example.com/products/';
console.log(new URL('shoes', base).href); // 'https://shop.example.com/products/shoes'
console.log(new URL('/cart', base).href); // 'https://shop.example.com/cart'
console.log(new URL('../about', base).href); // 'https://shop.example.com/about'
This mirrors exactly how a browser resolves a relative link (href="shoes") against the page it's on — useful when your server-side code needs the same resolution logic.
Reading and modifying query parameters together
const pageUrl = new URL('https://shop.example.com/search?q=laptop&page=1');
pageUrl.searchParams.set('page', '2'); // update an existing parameter
pageUrl.searchParams.append('sort', 'price'); // add a new one
pageUrl.searchParams.delete('q'); // remove one entirely
console.log(pageUrl.href);
// https://shop.example.com/search?page=2&sort=price
Where this shows up in practice
- Reading the path and query string of an incoming server request.
- Building outgoing API request URLs dynamically, with parameters computed at runtime.
- Validating that a URL a user submitted is actually well-formed, by catching the error
new URL()throws on invalid input:
function isValidUrl(str) {
try {
new URL(str);
return true;
} catch {
return false;
}
}
console.log(isValidUrl('https://example.com')); // true
console.log(isValidUrl('not a url')); // false