How to set the fragment part of a URL
By Flavio Copes
Learn how to programmatically set the fragment portion of a URL in JavaScript, the part after the # hash symbol, by assigning to window.location.hash.
To set the fragment part of a URL in JavaScript, you assign a value to window.location.hash. The fragment is the part after the # hash symbol.
I’ve had the need to do this programmatically. I was on index.html and I wanted to change the URL to something like index.html#second.
The reason for this was a bit unusual, but let’s say I had a table of contents but the links weren’t working as I wanted.
Here’s how I did it:
window.location.hash = 'second'
You don’t need to include the # in the value. The browser adds it for you.
What happens when you set it?
Three things, and none of them is a page reload:
The URL in the address bar updates to end with #second.
If the page contains an element with id="second", the browser scrolls to it. If no element matches, the URL still changes but nothing scrolls.
A new entry is added to the browser history. Pressing the back button takes you to the previous fragment.
That history behavior is what makes fragments handy for tables of contents: each section the user visits becomes a step they can navigate back through.
Reading the fragment back
window.location.hash also works as a getter, and this is where people trip up. The value you read back includes the hash symbol:
window.location.hash = 'second'
console.log(window.location.hash) //'#second'
So a comparison like window.location.hash === 'second' is always false. Strip the first character when you need the bare value:
const fragment = window.location.hash.slice(1) //'second'
Changing the fragment without adding history
Sometimes you update the fragment often, for example while the user scrolls, and you don’t want to fill the history with dozens of entries. In that case use history.replaceState() instead:
history.replaceState(null, '', '#second')
This rewrites the current URL in place. No new history entry, and no automatic scrolling either.
Reacting to fragment changes
If you want to run code when the fragment changes, listen for the hashchange event:
window.addEventListener('hashchange', () => {
console.log(window.location.hash)
})
This fires when you assign to location.hash, when the user clicks a # link, and when they use the back button. Notice that history.replaceState() does not fire it, so pick the technique that matches what you need.
Related posts about platform: