689

I either dreamt about chrome (dev channel) implementing a way to update the address bar via javascript (the path, not domain) without reloading the page or they really have done this.

However, I can't find the article I think I read.

Am I crazy or is there a way to do this (in Chrome)?

p.s. I'm not talking about window.location.hash, et al. If the above exists the answer to this question will be untrue.

Community
  • 1
  • 1
David Murdoch
  • 82,194
  • 38
  • 141
  • 186
  • 1
    @tobiaskienzler When that question was originally asked back in 2009, it was not possible. – David Murdoch Aug 24 '16 at 11:34
  • 5
    Of course not. But now it is, the _questions_ ask for the same. A shame though that the other one has an outdated answer accepted (by you, I noticed)... You know what? Let's dupe-close the other way around, no-one said the "original" has to be the older one, in fact there are precedents – Tobias Kienzler Aug 24 '16 at 11:45
  • @tobiaskienzler, the other question doesn't have an outdated accepted answer. – David Murdoch Aug 24 '16 at 11:48
  • ok, not outdated, but more complicated. Still, the two questions do appear to be pretty much the same to me, but maybe I'm missing a nuance here... – Tobias Kienzler Aug 24 '16 at 11:56
  • 2
    @TobiasKienzler it's a 6 years old question, why you have to bother with this question? Just enjoy the amazing answer and implement it on your application. For 6 years thousands of SO users agreed that it's an amazing questions, please leave it as it is. – Imam Assidiqqi Dec 24 '16 at 09:43

4 Answers4

921

You can now do this in most "modern" browsers!

Here is the original article I read (posted July 10, 2010): HTML5: Changing the browser-URL without refreshing page.

For a more in-depth look into pushState/replaceState/popstate (aka the HTML5 History API) see the MDN docs.

TL;DR, you can do this:

window.history.pushState("object or string", "Title", "/new-url");

See my answer to Modify the URL without reloading the page for a basic how-to.

Cavell Blood
  • 109
  • 1
  • 6
David Murdoch
  • 82,194
  • 38
  • 141
  • 186
  • 3
    Ah, the functionality is in WebKit and landed a few months ago . Nice find! – oldestlivingboy Jul 27 '10 at 01:46
  • 6
    this is now used by github, while tree navigation – Valerij Feb 22 '11 at 19:11
  • 1
    @Vprimachenko: Yup. And they break my back button every once in a while. – David Murdoch Feb 22 '11 at 19:27
  • This can now be done in Chrome, Safari, FF4+, and IE10pp3+! (From David Murdoch's answer to http://stackoverflow.com/questions/824349/modify-the-url-without-reloading-the-page ) – Zach Lysobey Dec 19 '11 at 17:48
  • What about IE9 and below? Any similar solutions for them? – shubniggurath Feb 26 '13 at 16:07
  • There are all sorts of `history` hacks out there. See this SO question for more info: http://stackoverflow.com/questions/2358928/whats-the-best-library-to-do-a-url-hash-history-in-jquery – David Murdoch Feb 26 '13 at 18:08
  • being able to store objects related to the history is frakkin great as well! – roberthuttinger Jul 02 '13 at 16:15
  • 13
    Protip: you can use relative paths with these functions as well (e.g. `../new-url` or `../../new-url`. They seem to do what you would expect in Chrome at least. – Mahn Aug 03 '13 at 09:29
  • 2
    I'd like to add that `window.replaceState` is much easier to set up and often preferable, e.g. when you want to update the URL after the user changes the value of some dropdown or search field. If you want to use `pushState`, then you also need to properly support `onpopstate` event. – Kos Jul 31 '16 at 08:06
  • What is “object or string” supposed to be? – fwyzard Mar 21 '20 at 18:57
  • @fwzard `state`. The `state` object is a JavaScript object which is associated with the new history entry created by `pushState()`. Whenever the user navigates to the new `state`, a `popstate` event is fired, and the `state` property of the event contains a copy of the history entry's `state` object. The `state` object can be anything that can be serialized. So it's actually more than just `"object or string"`. Docs: https://developer.mozilla.org/en-US/docs/Web/API/History/pushState – David Murdoch Mar 25 '20 at 22:11
175

Changing only what's after hash - old browsers

document.location.hash = 'lookAtMeNow';

Changing full URL. Chrome, Firefox, IE10+

history.pushState('data to be passed', 'Title of the page', '/test');

The above will add a new entry to the history so you can press Back button to go to the previous state. To change the URL in place without adding a new entry to history use

history.replaceState('data to be passed', 'Title of the page', '/test');

Try running these in the console now!

Pawel
  • 10,190
  • 4
  • 56
  • 60
  • 17
    `replaceState` was exactly what I needed, thanks for expanding on original response. – Choylton B. Higginbottom Sep 21 '16 at 23:07
  • 1
    'the domain and protocol must be the same as original!' this prevent some fishing site to change the address bar url. – Rick Sep 26 '17 at 10:49
  • 3
    You should not pass an absolute URL to this function. If you do, you most likely need to build it dynamically from the current scheme, host, and port - which is a lot of work when you could just make it a relative URL ("foo.html" or even "/foo.html") and let the browser take care of it. – DimeCadmium Jun 17 '18 at 05:20
  • 1
    @DimeCadmium nice simplification. Updated. – Pawel Jun 17 '18 at 20:02
  • `history.replaceState` add to history in ff 66.0b1 – azzamsa Jan 25 '19 at 18:09
  • @azzamsa must've been a bug. It's not happening in more recent versions – Pawel Oct 07 '20 at 10:09
36

Update to Davids answer to even detect browsers that do not support pushstate:

if (history.pushState) {
  window.history.pushState("object or string", "Title", "/new-url");
} else {
  document.location.href = "/new-url";
}
KenBuckley
  • 375
  • 2
  • 12
metamagikum
  • 959
  • 12
  • 18
8
var newurl = window.location.protocol + "//" + window.location.host + window.location.pathname + '?foo=bar';
window.history.pushState({path:newurl},'',newurl);
Kevin Mendez
  • 356
  • 3
  • 5
  • 9
    While this code snippet may solve the question, [including an explanation](//meta.stackexchange.com/questions/114762/explaining-entirely-code-based-answers) really helps to improve the quality of your post. Remember that you are answering the question for readers in the future, and those people might not know the reasons for your code suggestion. – MaxiMouse Mar 03 '20 at 18:03
  • @MaxiMouse thanks for your sugerence, i will take it in mind. – Kevin Mendez Apr 19 '20 at 02:39
  • 1
    Suggested edit: const url = new URL(window.location); url.searchParams.set('foo', 'bar'); window.history.pushState({}, '', url); – Mattia Pontonio Nov 15 '20 at 17:45