For all modern developers of the web, Internet Explorer is the bane of existence (I'll explain why in a future post). Depending on your user base, you may still have to support a variety of browsers, both new and old. This causes difficulty in ensuring the code you write is compatible on so many platforms. But before we get into that, lets take a look at some data and see the level of severity.

Some stats in yo' face

Even though it's 2016, you may still be surprised to hear that a decent percentage of web consumption is still done on an outdated version of Internet Explorer. Don't believe me? Here is a screenshot of the last 12 months of browser usage statistics (courtesy of Statscounter).

As you can see from the graph, in the United States, 7.16% of users are still using an older version of Internet Explorer and a staggering 2.76% of that is still using IE8, which doesn't support ECMAScript 5, and IE9 only partially supports it!

To solve this problem developers can take multiple combinations of approach. Developers can incorporate a polyfill library, drop support, add HTML conditional comments, or sprinkle some Javascript condition checks to execute different blocks of code for each browser. Lets say you have no choice but to write some condition checks in your Javascript to detect the Internet Explorer version, how do you go about doing this accurately?

Detecting internet explorer

In this post I will go over how to detect the Internet Explorer version more accurately.

Uh... dude, there are like a BAJILLION documents on how to do this.

That's true, but there are some nuances with detecting the right version of Internet Explorer that's not addressed or ill-documented. For example, Microsoft has documented some useful ways of detecting Internet Explorer. In particular, take note on their section of parsing the user agent string. This section does not discuss a key implementation detail that is missing, which can cause you some grief.

As a result, there are some popular websites and tools that may have implemented an incomplete or even incorrect Internet Explorer checker.

I've seen this incompleteness on some popular tools that include both Optimizely and even Google Analytics. At Intuit, this bug has directly affected our product - Google Analytics mis-reported our browser usage stats and Optimizely would not place our users in a proper test bucket. So what is this bug?

The missing trident

Internet Explorer has always used a proprietary layout engine for each version of IE. Starting with IE8, it began reporting the version of this layout engine as part of the user agent string. The layout engine is named Trident; with every new version of Internet Explorer, there is a new version of Trident. You can read more about IE's user agent string here and read more about the all the possible user agent strings here.

How does this affect you? Well as I mentioned earlier, a lot of IE checkers only check against the MSIE version specified in the user-agent string. However, it is possible that when you go to a webpage, Internet Explorer can report back a different MSIE version, even if it is an up to date version that can render the page with the latest web standards. In fact, IE11 does not even report an MSIE version!!!

Yep that's right. For example, you can have Internet Explorer 10 installed in your computer, but when you open up a webpage, the user agent string might say it's MSIE 8. The page will then potentially freak out and render incorrectly. However, it's technically IE 10, which means it's using the latest rendering engine, so it should be able to conform to the latest web standards! There are many ways this can happen and it's all documented in MSDN. Want to try it yourself? Pop open the developer tools (F12) on Internet Explorer, modify your document mode, and check out the user agent string result.

I have IE11 installed on my desktop. When I switched the document mode to 8, the user agent string reports the browser as MSIE 8, but look at the trident string! It still reports 7.0!

Implementing a more accurate IE checker

Given this discovery, we can write a more accurate Internet Explorer checker. The example on MSDN is outdated as well and won't work for IE11, so lets tweak that a bit. Now for some free code!

function getMSIEVersion()
{
  var version = -1;
  
  if (navigator)
  {
    var userAgent = navigator.userAgent;
    var regEx = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    
    if (regEx.exec(userAgent) != null) {
      version = parseFloat(RegExp.$1);
    }
  }

  return version;
}

function getTridentVersion()
{
  var version = -1;
  
  if (navigator)
  {
    var userAgent = navigator.userAgent;
    var regEx = new RegExp("Trident/([0-9]{1,}[\.0-9]{0,})");
    
    if (regEx.exec(userAgent) != null) {
      version = parseFloat(RegExp.$1);
    }
  }

  return version;
}

All we're doing implementing two functions to check the Trident string and the MSIE version. Depending on your use case, you'll want to check on the combination of both the Trident and MSIE versions to figure out what to do next. To be honest, you really only need the Trident token to get a true representation of the IE version, then use the MSIE token to help you determine the current document mode.

That's it! It's as simple as that!

"Psh, I only deal with the latest and greatest"

If that is the case for you, then lucky you! You are one of few who doesn't have to worry about this IE bullhonky. So celebrate with some cake you lucky, glorious bastard!

But for the unlucky few (like myself), depending on the primary user base for your product, you may still have to support older browsers. As a byproduct, the percentage of your users who still use IE8 or IE9 may even be higher than the global stat! So no cake for me...