10
votes

I am using AJAX to load main content of the page. Using history.pushstate(Object:State, String:Title, String:URL) - I am able to update the URL in the address bar and navigate back in the history.

However the title parameter appears to have no effect. Neither does the window title change nor the title of the entries in the 'history list' (perhaps both of them are same anyway).

What am I doing wrong?

Update: title param is simply ignored in chrome. http://lists.whatwg.org/pipermail/whatwg-whatwg.org/2010-June/026827.html

3
I am work-around this simply by using: document.title = "NEW_TITLE" before a call to history.pushstate but why does it not work the way its supposed to?Ujjwal Singh
You're not doing anything wrong, that's the way it works. The history API changes the URL and you have to do the rest, like change the documents contents, including the title.adeneo
then does it mean - the title param is a dummy?Ujjwal Singh
No, the title param is not a dummy, it just does'nt change the documents title automagically, as those are just two different things with a similar name.adeneo
okay, but then what is the use of the title param?Ujjwal Singh

3 Answers

14
votes

The title parameter is not the window title.
It may be used as a title of the state but some browsers like Chrome simply ignore it.

4
votes

As @ujjwal-singh has already written in his answer the 2nd parameter title may be used as a label for the entry in the history but it is optional and the browser can ignore it and decide to use a different source for the title. The note below bullet point 8 at chapter 5.5.2 of the HTML 5 specification states

The title is purely advisory. User agents might use the title in the user interface.

This is how Chrome and Firefox work. Hence, the following code should lead to a consistent user experience among all major browsers

document.title = myTitle;
history.pushState( myState, myTitle, myURL );

This code also updates the title of the document and Chrome and Firefox are supposed to use this one.

However, it does not work as expected and you will experience a weird off-by-one bug. (This is at least true for FF up to version 45 and Chrome 51.) The problem is that the UI is not updated immediately but only after the JS call stack becomes empty. Hence, pushState will still use the old (out-dated) title, because the new title of the document is not yet applied to the DOM. On the next call of this code snippet pushState uses the previously changed title and so on.

If the user picks an item from the history, the user is mislead to a different page than the user expects, because the labels of each history entry and the actual destination of the history entry are out-of-sync by one.

However, this looks like a bug in Chrome and Firefox to me. Although the UI is only updated after JS terminates pushState should already use the new title. I have filed a bug report both to Chromium and Mozilla.

1
votes

I doesn't know why that works like that, but because of comment of Rounin which are next:

I have window.history.pushState(myStateObject, myNewTitle, myNewURL); document.title = myNewTitle; working in Firefox 72 in Jan 2020. I have no idea how it's never occurred to me before that a document.title can be reset live. Excellent heads up.

I've suddenly found that in Firefox 91.0b9 you have to put pushState firstly, and secondly you have to change title. And then history manager in Ff 91.0b9 changing exact page that pushed state and not simular closer page with slightly different uri. In my case if document.title changed first, history management thing changes last two records with simular links of the site.

For example if some /page will be changed to /page/2, and you change title and then will make pushState, then both records titles will be changed to that one that you specified in document title or may be it's related to title in pushState. So when document.title called secondly it is works normally

Example (works):

window.history.pushState(myStateObject, myNewTitle, myNewURL);
document.title = myNewTitle;

And not like it is probably suppose to be (not works):

document.title = myNewTitle;
window.history.pushState(myStateObject, myNewTitle, myNewURL);

Thank you to the Rounin!