Web APIs Cheatsheet
History and URL
Use this Web APIs reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.
window.location
// Read-only snapshot of current URL location.href; // 'https://example.com:8080/path?q=1#hash' location.origin; // 'https://example.com:8080' location.protocol; // 'https:' location.host; // 'example.com:8080' location.hostname; // 'example.com' location.port; // '8080' location.pathname; // '/path' location.search; // '?q=1' location.hash; // '#hash' // Navigate (adds to history) location.href = 'https://example.com/new'; location.assign('https://example.com/new'); // Navigate without adding to history location.replace('https://example.com/new'); // Reload location.reload(); // Write individual parts (triggers navigation) location.pathname = '/other'; location.search = '?page=2'; location.hash = '#section';
History API
Basic Navigation
history.length; // number of entries in session history history.scrollRestoration; // 'auto' | 'manual' history.state; // current state object (or null) history.back(); // equivalent to browser Back history.forward(); // equivalent to browser Forward history.go(0); // reload history.go(-2); // 2 steps back history.go(1); // 1 step forward
pushState and replaceState
// pushState(state, unused, url) // url must be same origin; can be relative; does NOT trigger navigation history.pushState({ page: 2 }, '', '/products?page=2'); history.pushState(null, '', '/about'); // replaceState — updates current entry without adding a new one history.replaceState({ page: 2 }, '', '/products?page=2');
pushState | replaceState | |
|---|---|---|
| Adds to history stack | Yes | No |
Fires popstate | No | No |
| Triggers page load | No | No |
| URL must be same-origin | Yes | Yes |
popstate Event
// Fires on back/forward navigation (NOT on pushState/replaceState) window.addEventListener('popstate', e => { console.log('State:', e.state); // the state object passed to push/replace console.log('Path:', location.pathname); renderPage(location.pathname, e.state); });
popstatefires when the user navigates the history stack (back/forward button orhistory.go()). It does not fire forpushState/replaceState.
hashchange Event
window.addEventListener('hashchange', e => { e.oldURL; // full URL before hash change e.newURL; // full URL after hash change console.log(location.hash); // e.g. '#section-2' });
URL API
const url = new URL('https://example.com:8080/path?q=hello&page=2#top'); url.href; // full URL string url.origin; // 'https://example.com:8080' url.protocol; // 'https:' url.host; // 'example.com:8080' url.hostname; // 'example.com' url.port; // '8080' url.pathname; // '/path' url.search; // '?q=hello&page=2' url.hash; // '#top' url.username; // '' (http://user:pass@host) url.password; // '' // Modify and serialize url.pathname = '/new-path'; url.searchParams.set('page', 3); url.toString(); // updated URL string // Relative URL (resolve against base) const rel = new URL('/about', 'https://example.com'); rel.href; // 'https://example.com/about' // Static URL.canParse('not a url'); // false URL.parse('https://example.com'); // URL | null (no throw)
URLSearchParams
// From URL const params = new URL(location.href).searchParams; // From string const params = new URLSearchParams('q=hello&page=2&tag=js&tag=ts'); // From object const params = new URLSearchParams({ q: 'hello', page: '2' }); // From entries const params = new URLSearchParams([['q', 'hello'], ['page', '2']]); // Read params.get('q'); // 'hello' (first value) or null params.getAll('tag'); // ['js', 'ts'] params.has('page'); // true params.size; // number of entries // Write params.set('page', '3'); // replace all 'page' values params.append('tag', 'css'); // add (keeps existing) params.delete('q'); // remove all 'q' params.delete('tag', 'js'); // remove specific value (modern) params.sort(); // sort by key (stable, Unicode order) // Iterate for (const [key, value] of params) { /* … */ } params.forEach((value, key) => { /* … */ }); [...params.keys()]; [...params.values()]; [...params.entries()]; // Serialize params.toString(); // 'page=3&tag=ts&tag=css' (URL-encoded) // Attach to URL url.search = params.toString(); // or url.searchParams.set('key', 'val'); // URLSearchParams is live on URL object
SPA Router Pattern (History API)
// Link interception document.addEventListener('click', e => { const a = e.target.closest('a[href]'); if (!a) return; const url = new URL(a.href); if (url.origin !== location.origin) return; // let external links through e.preventDefault(); history.pushState(null, '', url.pathname + url.search + url.hash); router(url.pathname); }); // Handle back/forward window.addEventListener('popstate', () => router(location.pathname)); // Initial load router(location.pathname); function router(path) { const route = routes.find(r => r.pattern.test(path)); if (route) route.render(path); }
URL Encoding Utilities
// Encode a full URL (keeps special URL chars) encodeURI('https://example.com/path with spaces'); // 'https://example.com/path%20with%20spaces' // Encode a URI component (encodes everything except unreserved chars) encodeURIComponent('hello world & more'); // 'hello%20world%20%26%20more' decodeURI('%20'); decodeURIComponent('%20'); // URLSearchParams handles encoding automatically const p = new URLSearchParams({ q: 'hello world & more' }); p.toString(); // 'q=hello+world+%26+more' (+ for spaces in query strings)
Gotchas
pushState/replaceStateURLs must be same-origin — passing a cross-origin URL throws aSecurityError.- The second argument to
pushState/replaceState(title) is ignored by all browsers.history.stateis serialized with the structured clone algorithm — functions, DOM nodes, and class instances are not preserved.popstatedoes NOT fire on page load — readhistory.statedirectly on initial render.URLSearchParamsuses+for spaces when serialized, but%20within URL path components.