javascriptbrowser-detection

How to detect Safari, Chrome, IE, Firefox and Opera browsers?


I have 5 addons/extensions for Firefox, Chrome, Internet Explorer(IE), Opera, and Safari.

How can I correctly recognize the user browser and redirect (once an install button has been clicked) to download the corresponding addon?


Solution

  • Googling for browser reliable detection often results in checking the User agent string. This method is not reliable, because it's trivial to spoof this value.
    I've written a method to detect browsers by duck-typing.

    Only use the browser detection method if it's truly necessary, such as showing browser-specific instructions to install an extension. Use feature detection when possible.

    Demo: https://jsfiddle.net/6spj1059/

    // Opera 8.0+
    var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
    
    // Firefox 1.0+
    var isFirefox = typeof InstallTrigger !== 'undefined';
    
    // Safari 3.0+ "[object HTMLElementConstructor]" 
    var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && window['safari'].pushNotification));
    
    // Internet Explorer 6-11
    var isIE = /*@cc_on!@*/false || !!document.documentMode;
    
    // Edge 20+
    var isEdge = !isIE && !!window.StyleMedia;
    
    // Chrome 1 - 79
    var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
    
    // Edge (based on chromium) detection
    var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);
    
    // Blink engine detection
    var isBlink = (isChrome || isOpera) && !!window.CSS;
    
    
    var output = 'Detecting browsers by ducktyping:<hr>';
    output += 'isFirefox: ' + isFirefox + '<br>';
    output += 'isChrome: ' + isChrome + '<br>';
    output += 'isSafari: ' + isSafari + '<br>';
    output += 'isOpera: ' + isOpera + '<br>';
    output += 'isIE: ' + isIE + '<br>';
    output += 'isEdge: ' + isEdge + '<br>';
    output += 'isEdgeChromium: ' + isEdgeChromium + '<br>';
    output += 'isBlink: ' + isBlink + '<br>';
    document.body.innerHTML = output;

    Analysis of reliability

    The previous method depended on properties of the rendering engine (-moz-box-sizing and -webkit-transform) to detect the browser. These prefixes will eventually be dropped, so to make detection even more robust, I switched to browser-specific characteristics:

    Successfully tested in:

    Updated in November 2016 to include detection of Safari browsers from 9.1.3 and upwards

    Updated in August 2018 to update the latest successful tests on chrome, firefox IE and edge.

    Updated in January 2019 to fix chrome detection (because of the window.chrome.webstore deprecation) and include the latest successful tests on chrome.

    Updated in December 2019 to add Edge based on Chromium detection (based on the @Nimesh comment).