To modify the URL without reloading the page in JavaScript, use the History API (pushState
or replaceState
) or manipulate the hash fragment. Here’s how to do it:
1. Using history.pushState()
(Modern Approach)
Modify the URL and add a new entry to the browser’s history stack without reloading:
// Syntax: history.pushState(state, title, url)
history.pushState({ data: 'someState' }, '', '/new-path');
- Example:
// Change URL to "/products" without reloading
history.pushState(null, '', '/products');
2. Using history.replaceState()
Replace the current URL in the history stack (doesn’t create a back/forward entry):
history.replaceState({ data: 'replacedState' }, '', '/updated-path');
- Use case: Update the URL after authentication or redirects.
3. Using Hash Fragments (Legacy Approach)
Modify the part of the URL after #
(triggers hashchange
event):
window.location.hash = 'section-2'; // URL becomes: http://example.com/#section-2
- Listen for hash changes:
window.addEventListener('hashchange', () => {
console.log('Hash changed to:', window.location.hash);
});
Key Differences
Method | Page Reload? | History Entry? | Compatibility |
---|---|---|---|
pushState | No | Creates entry | Modern browsers |
replaceState | No | Replaces entry | Modern browsers |
window.location.hash | No | Creates entry | All browsers |
Handling Back/Forward Navigation
Use the popstate
event to detect when the user navigates history:
window.addEventListener('popstate', (event) => {
console.log('Navigated to:', window.location.pathname);
// Access state data: event.state
});
Full Example
// Change URL to "/settings" and track state
history.pushState({ page: 'settings' }, '', '/settings');
// Later, handle back/forward navigation
window.addEventListener('popstate', (event) => {
if (event.state?.page === 'settings') {
loadSettingsPage(); // Your custom logic
}
});
Use Cases
- Single-page applications (SPAs) for route management.
- Updating the URL after filtering/searching content.
- Preserving state in AJAX-driven pages.
Caveats
- Security: You can only modify the URL to the same origin (no cross-domain changes).
- SEO: Use server-side rendering or
<meta>
tags for crawlers if relying on URL paths. - Browser Support:
pushState
works in IE10+, while hash fragments work everywhere.
Use pushState
/replaceState
for clean URLs in modern apps, and fall back to hashes for legacy support.