We have a provider hosted web part on our page layout. When a user visits any page they cannot use the back button, when they try it redirects back to the current page.

The web part is hosted in an iFrame with a src of appredirect.aspx which appears in the history so when a user hits back they are actually going to appredirect.aspx not the previous page.

Does anyone know a way around this? We are hosting on SharePoint Online, so we can't edit any of the underlying files.

1 Answer 1


Load the javascript at the first page in the provider hosted app.

A popstate event is dispatched to the window every time the active history entry changes between two history entries for the same document.

-> Add history record for the same page (provider hosted start url)

-> When you press the back button, popstate event is triggered and loads correct history page

I use the pushState to add a history item without reloading the page with the same document url.

Of course, the history records are identically in Firefox & Chrome... except IE. Which does some stuff I don't understand at all. It works if you go back one more step though. -> I added a browser check and go back one more page in history for internet explorer.

It's a bit nasty but it works quite well. It even works if you browse pages inside the iframe and then go back.

I expect it could give some strange behaviour if you click on a few links in the iframe, and end up on the first page. Pressing the back/forward button in that situation will also trigger the event.

window.onpopstate = function (event) {
    if (navigator.sayswho.indexOf("IE") != -1) {
    else {

if (document.referrer.indexOf("_layouts/15/appredirect.aspx?") != -1) {
    // Add history so when you click on the back button, the onpopstate event is 
    // triggered since the previous page is on the same document.
    history.pushState({}, "reload", document.location.href);

// Just to test if internet explorer is used, change with your own if you want :-)
navigator.sayswho = (function () {
var ua = navigator.userAgent, tem,
M = ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
if (/trident/i.test(M[1])) {
    tem = /\brv[ :]+(\d+)/g.exec(ua) || [];
    return 'IE ' + (tem[1] || '');
if (M[1] === 'Chrome') {
    tem = ua.match(/\bOPR\/(\d+)/)
    if (tem != null) return 'Opera ' + tem[1];
M = M[2] ? [M[1], M[2]] : [navigator.appName, navigator.appVersion, '-?'];
if ((tem = ua.match(/version\/(\d+)/i)) != null) M.splice(1, 1, tem[1]);
return M.join(' ');

I have tested it, and it seems to work decently.

It works for IE11, Firefox 31.0 & chrome 36.

Requires HTML5 History API, click here for supported browsers.

  • I tried doing something very similar, but our client is using ie9 and I couldn't find a way to get this to work in ie 9. It looks like this has the same limitation. I'm gong to see if there are any shims that might make this work in ie9.
    – Estyn
    Commented Jul 31, 2014 at 20:01
  • Give this a go: github.com/browserstate/history.js Commented Jul 31, 2014 at 21:48
  • Doesn't look like it will work I'm going to re-write the app as a sharepoint hosted webpart and create my own iFrame that I can control. I'm marking yoru answer as correct as it should help anyone that doesn't have an ie9 requirement.
    – Estyn
    Commented Aug 1, 2014 at 21:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.