Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Detect if the browser is running in Private mode (Promise based)
// uncomment if you are transpiling with Babel + Webpack
// const { window, document } = global;
/**
* Lightweight script to detect whether the browser is running in Private mode.
* @returns {Promise}
*
* Live demo:
* @see http://live.datatables.net/piduzelo/1
*
* This snippet uses ES2015 syntax. If you want to run it in old browsers, transpile it with Babel:
* @see https://babeljs.io/repl
*
* This snippet uses Promises. If you want to run it in old browsers, polyfill it:
* @see https://cdn.jsdelivr.net/npm/es6-promise@4/dist/es6-promise.auto.min.js
*
* More Promise Polyfills:
* @see https://ourcodeworld.com/articles/read/316/top-5-best-javascript-promises-polyfills
*/
function isPrivateMode() {
return new Promise((resolve) => {
const yes = () => resolve(true); // is in private mode
const not = () => resolve(false); // not in private mode
const testLocalStorage = () => {
try {
if (localStorage.length) not();
else {
localStorage.x = 1;
localStorage.removeItem('x');
not();
}
} catch (e) {
// Safari only enables cookie in private mode
// if cookie is disabled, then all client side storage is disabled
// if all client side storage is disabled, then there is no point
// in using private mode
navigator.cookieEnabled ? yes() : not();
}
};
// Chrome & Opera
var fs = window.webkitRequestFileSystem || window.RequestFileSystem;
if (fs) {
return void fs(window.TEMPORARY, 100, not, yes);
}
// Firefox
if ('MozAppearance' in document.documentElement.style) {
if (indexedDB === null) return yes();
const db = indexedDB.open('test');
db.onerror = yes;
db.onsuccess = not;
return void 0;
}
// Safari
const isSafari = navigator.userAgent.match(/Version\/([0-9\._]+).*Safari/);
if (isSafari) {
const version = parseInt(isSafari[1], 10);
if (version < 11) return testLocalStorage();
try {
window.openDatabase(null, null, null, null);
return not();
} catch (_) {
return yes();
}
}
// IE10+ & Edge InPrivate
if (!window.indexedDB && (window.PointerEvent || window.MSPointerEvent)) {
return yes();
}
// default navigation mode
return not();
});
}
isPrivateMode().then(function (isPrivate) {
console.log('Browsing in private mode? ', isPrivate);
});
@jherax

This comment has been minimized.

Copy link
Owner Author

commented Dec 1, 2016

Ideas were gathered from this post on stackoverflow: Detecting if a browser is using Private Browsing mode

@jmboiton

This comment has been minimized.

Copy link

commented Jun 29, 2017

I would like to highlight this comment from the same stackoverflow question :

Promises aren't natively supported in IE10 or 11. I'd assume you used a polyfill here

@lukasotocerny

This comment has been minimized.

Copy link

commented Dec 27, 2017

It fails to detect Private mode in Safari Version 11.0.2

@subversivo58

This comment has been minimized.

Copy link

commented Jan 24, 2018

Suggest: fix Chrome and Opera handler... using RequestFileSystem third param is targed to success and last for error, like:

return void window.webkitRequestFileSystem(0, 0, on, off);
@Maykonn

This comment has been minimized.

Copy link

commented Jul 27, 2018

@gaurav150493

This comment has been minimized.

Copy link

commented Sep 24, 2018

It fails to detect Private mode in Safari Version 11.0.2

try {
  window.openDatabase(null, null, null, null);
} catch (_) {
  isPrivate = true;
};

Use this code for iOS > 11

@Elastic1

This comment has been minimized.

Copy link

commented Nov 20, 2018

for safari

    const isSafari = navigator.userAgent.match(/Version\/([0-9\._]+).*Safari/);
    if (isSafari) {
      const version = parseInt(isSafari[1], 10);
      if (version >= 11) {
         try {
           window.openDatabase(null, null, null, null);
           return off();
         } catch (_) {
           return on();
         };
      } else if (version < 11) {
        return testLocalStorage();
      }
   }
@jherax

This comment has been minimized.

Copy link
Owner Author

commented Feb 6, 2019

for safari

const isSafari = ...

Thanks for the improvement @Elastic1

Added to the snippet.

@msmith7904

This comment has been minimized.

Copy link

commented Jun 20, 2019

This is not working for me on Mobile Chrome v 74.0.3729.155.

@jherax

This comment has been minimized.

Copy link
Owner Author

commented Jul 5, 2019

This is not working for me on Mobile Chrome v 74.0.3729.155.

@msmith7904 I updated snippet for chrome detection:

  // Chrome & Opera
  var fs = window.webkitRequestFileSystem || window.RequestFileSystem;
  if (fs) {
    return void fs(window.TEMPORARY, 100, not, yes);
  }

However, take into account what people from Chrome said, paraphrasing...

Google is removing the ability to detect Private Browsing Mode permanently in Chrome 76 onwards. So, if you're wanting to detect private browsing it's now impossible (unless you find a way to do it that Google hasn't found). The ability to detect private browsing mode has been acknowledged as a bug and was never intended.

There should never be a situation where needing to detect private browsing mode on a normal day-to-day website is ever needed. People are choosing to browse anonymously and or not anonymously for their own reasons.

Browsers like Chrome and Firefox do not disable functionality like localStorage any more. They simply namespace it in a temporary location to prevent websites that use it from erroring out. Once you're finished browsing, the namespace is erased and nothing is saved. If you are testing for localStorage support regardless of mode, it will always return true for browsers that support it.

Other means of detecting private mode in Chrome specifically have been completely patched and will no longer work.

If it is required internally by a company, you should develop a browser plugin. Chrome and Firefox, in particular, expose internal API's which allow plugins to check if the user is in private browsing/incognito mode and action accordingly. It cannot be done outside of a plugin.


See the following links:

@jherax

This comment has been minimized.

Copy link
Owner Author

commented Jul 5, 2019

I wrote a JSBin (which works with IE), check it out:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.