It seems like the old detection methods which have worked for iOS 11 and respective Safari version(s) do not work anymore.
I have tried this script: https://gist.github.com/cou929/7973956
But it doesn't work for safari on iOS 12 and also doesn't work for Chrome 69 on iOS 12.
This quite new library is also not working for iOS 12 browsers:
https://github.com/Maykonn/js-detect-incognito-private-browsing-paywall
So is there any solution for iOS 12 browsers yet?
BostonGlobe seems to have a solution, but I have no idea how they did it:
https://www.bostonglobe.com/sports/redsox/2018/10/09/redsox/D66J59viZ1qxyZlhI18l8L/story.html
(If you want to read an BostonGlobe.com article in incognito / private mode you get a screen which asks you to log in)
Chrome Devtools => The module to detect incognito/private mode is called "detect-private-browsing" located at webpack:///./~/detect-private-browsing/index.js
// ./~/detect-private-browsing/index.js
function retry(isDone, next) {
var current_trial = 0, max_retry = 50, interval = 10, is_timeout = false;
var id = window.setInterval(
function() {
if (isDone()) {
window.clearInterval(id);
next(is_timeout);
}
if (current_trial++ > max_retry) {
window.clearInterval(id);
is_timeout = true;
next(is_timeout);
}
},
10
);
}
function isIE10OrLater(user_agent) {
var ua = user_agent.toLowerCase();
if (ua.indexOf('msie') === 0 && ua.indexOf('trident') === 0) {
return false;
}
var match = /(?:msie|rv:)\s?([\d\.]+)/.exec(ua);
if (match && parseInt(match[1], 10) >= 10) {
return true;
}
// MS Edge Detection from this gist: https://gist.github.com/cou929/7973956
var edge = /edge/.exec(ua);
if (edge && edge[0] == "edge") {
return true;
}
return false;
}
module.exports = {
detectPrivateMode: function(callback) {
var is_private;
if (window.webkitRequestFileSystem) {
window.webkitRequestFileSystem(
window.TEMPORARY, 1,
function() {
is_private = false;
},
function(e) {
console.log(e);
is_private = true;
}
);
} else if (window.indexedDB && /Firefox/.test(window.navigator.userAgent)) {
var db;
try {
db = window.indexedDB.open('test');
} catch(e) {
is_private = true;
}
if (typeof is_private === 'undefined') {
retry(
function isDone() {
return db.readyState === 'done' ? true : false;
},
function next(is_timeout) {
if (!is_timeout) {
is_private = db.result ? false : true;
}
}
);
}
} else if (isIE10OrLater(window.navigator.userAgent)) {
is_private = false;
try {
if (!window.indexedDB) {
is_private = true;
}
} catch (e) {
is_private = true;
}
} else if (window.localStorage && /Safari/.test(window.navigator.userAgent)) {
// One-off check for weird sports 2.0 polyfill
// This also impacts iOS Firefox and Chrome (newer versions), apparently
// @see bglobe-js/containers/App.js:116
if (window.safariIncognito) {
is_private = true;
} else {
try {
window.openDatabase(null, null, null, null);
} catch (e) {
is_private = true;
}
try {
window.localStorage.setItem('test', 1);
} catch(e) {
is_private = true;
}
}
if (typeof is_private === 'undefined') {
is_private = false;
window.localStorage.removeItem('test');
}
}
retry(
function isDone() {
return typeof is_private !== 'undefined' ? true : false;
},
function next(is_timeout) {
callback(is_private);
}
);
}
};