50

Is there any way to detect if current page came from back button?

I want to load data from cookie only if current page came from back button.

Valter
  • 2,859
  • 5
  • 30
  • 51
  • 3
    Does this answer your question? [How do I detect if a user has got to a page using the back button?](https://stackoverflow.com/questions/829046/how-do-i-detect-if-a-user-has-got-to-a-page-using-the-back-button) – getup8 Jan 08 '20 at 07:35

7 Answers7

26

Note: This is reported to no longer work in the latest versions of Chrome.

When a user goes back a page, any visible form data is preserved, while any JavaScript variables are reset. I say 'visible' form data, as hidden fields seem not to be preserved, but invisible inputs are.

You can use this to your advantage in order to detect whether the page was an initial load, or had already been loaded previously such as from a back button click.

Create a invisible input field (not type 'hidden') with a value of '0', and within a DOM ready loader check to see if the value has been set to '1'; if it has you know the page has already been loaded, such as from a back button; if it is still '0' then the page has initially loaded for the first time, set the value to '1'.

Note: This is a bit delicate in the way it works, and probably doesn't work in all browsers; I built it with Chrome in mind.

  • The DOM needs to be loaded; not all ready functions work. The one below does, so does the JQuery ready; however (function() { }) in my instance does not.
  • The Input cannot be of type="hidden". Set style="display:none;" on the input instead.

.

<input id="backbuttonstate" type="text" value="0" style="display:none;" />
<script>
document.addEventListener('DOMContentLoaded', function () {
   var ibackbutton = document.getElementById("backbuttonstate");
   if (ibackbutton.value == "0") {
     // Page has been loaded for the first time - Set marker
     ibackbutton.value = "1";
     alert('First time load');
   } else {
     // Back button has been fired.. Do Something different..
     alert('Previously loaded - Returned from Back button');
   }
}, false);
</script>
Radderz
  • 2,770
  • 4
  • 28
  • 40
  • 2
    Yep worked well for me, tested in Chrome 64 and IE11. Key was invisible input rather than type="hidden" – Matt Kemp Mar 14 '18 at 01:35
  • Nice. A similar/alternative answer [here](https://stackoverflow.com/a/20899422/1526703) – Anupam Mar 30 '18 at 07:14
  • @Radderz For me it does work in Chrome 68 and Firefox 48, but it doesn't in IE11. Also if you use jQuery it works if you write "ibackbutton.val("1");" but not "ibackbutton.attr('value', "1");". Why is that? – kostr22 Aug 28 '18 at 08:56
  • @kostr22 I agree, it is very temperamental as different browsers behave in different ways; even jQuery has slightly different behaviours behind the scene as seen with .val and .attr methods, which can fire events at different stages in the page lifecycle. My recommendation is to not use jQuery but keep with raw javascript as it can potentially introduce extra failures with browsers or when new updates are released. It would be very nice to have a fix which supports IE11 - if you develop one please share! – Radderz Aug 28 '18 at 10:04
  • 1
    does not work for me in chrome 83. input value gets initialized after event, so i am seeing alert('First time load'); every time – Yehor Androsov Jun 29 '20 at 13:38
  • the 'invisible input field' does not remember i Chrome so it doesn't work – pHoutved Aug 06 '20 at 10:01
25

For a simpler check, there're Navigation Timing API Spec (already deprecated, but widely supported) and Navigation Timing Level 2 API Spec (working draft, supported by major browser)

if (window.performance) {
     var navEntries = window.performance.getEntriesByType('navigation');
     if (navEntries.length > 0 && navEntries[0].type === 'back_forward') {
          console.log('As per API lv2, this page is load from back/forward');
     } else if (window.performance.navigation
          && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
          console.log('As per API lv1, this page is load from back/forward');
     } else {
          console.log('This is normal page load');
     }
} else {
     console.log("Unfortunately, your browser doesn't support this API");
}
Montri M
  • 1,716
  • 14
  • 12
  • How do I know whether it is back or forward? I can't grasp the logic behind smashing those two together. Why haven't they provided a separate 'back' and separate 'forward' state? – Silidrone Jan 25 '22 at 08:46
  • Well, unfortunately this does not work with SPA (single page application), as the `type` is always `'reload'` – Kostiantyn Ko Jul 22 '23 at 19:54
16
 if (window.performance && window.performance.navigation.type == window.performance.navigation.TYPE_BACK_FORWARD) {
        $('.formName').get(0).reset();
    }
user3793702
  • 191
  • 1
  • 7
  • 7
    Please add some explanation to your code. Code-only answers tend to be confusing and not useful to other readers, and can attract downvotes that way. – Jesse Jun 20 '18 at 12:58
  • 1
    "**Deprecated**: This feature is no longer recommended. Though some browsers might still support it, it may have already been removed from the relevant web standards, may be in the process of being dropped, or may only be kept for compatibility purposes." [(source)](https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigation/type) – epineda Feb 24 '22 at 03:53
9

Use pageshow event to detect back or forward buttons:

$(window).bind("pageshow", function(event) {
    if (event.originalEvent.persisted) {
        Alert("User clicked on back button!");
    }
});

For more details you can check pageshow event in here .

Yusef
  • 124
  • 1
  • 4
3

In addition to @Radderz answer, I had to add setTimeout to make their solution work in chrome 83. Otherwise, I would only see 'First time load' alert.

In the HTML:

<input id="backbuttonstate" type="text" value="0" style="display:none;" />

In the script:

document.addEventListener('DOMContentLoaded', function () {

    var ibackbutton = document.getElementById("backbuttonstate");

    setTimeout(function () {

        if (ibackbutton.value == "0") {
            // Page has been loaded for the first time - Set marker
            ibackbutton.value = "1";
            alert('First time load');
        } else {
            // Back button has been fired.. Do Something different..
            alert('Previously loaded - Returned from Back button');
        }

    }, 200);

}, false);
ecraig12345
  • 2,328
  • 1
  • 19
  • 26
Yehor Androsov
  • 4,885
  • 2
  • 23
  • 40
2

I think this could be done with sessionStorage if you are working with pages within your project(This does not take external pages into account). Off the top of my head, when you are on your "Main Page" then you click a link and go to the next page.

On that next page, you can set a value in sessionStorage like:

sessionStorage.setItem('doSomething', 'yes');

Then back to your Main page, you can have a condition like:

const sCheckSession = sessionStorage.getItem('doSomething');
if(sCheckSession == 'yes') {
  // do something crazy, then reset your reference to no
  // so it wont interfere with anything else
  sessionStorage.setItem('doSomething', 'no');
}
UXCODA
  • 1,118
  • 2
  • 18
  • 33
  • with this method, you trap in after browser closed and open again. When reopen browser and go the url, your method fire an alarm at the first visit, but this is not a to come back operation. – Serhat MERCAN May 28 '21 at 23:25
0

Basically, you can't because of browser restrictions. HTML5 history API, the onpopstate event will be triggered when navigating to back page. But this will fire even if u use application navigation.

alternative solution refer - How to Detect Browser Back Button event - Cross Browser

Punit Gajjar
  • 4,937
  • 7
  • 35
  • 70