Server-Side Device Detection With JavaScript

Advertisement

There are many strategies to choose from when developing a modern, device independent website nowadays. How should capabilities of the device or browser be determined? Should the presentation logic be server side or client side? Traditionally, mobile optimization had to happen server side.

Over the last couple of years, Responsive Web Design and tools like Modernizr1 have become very popular. Recently, combination techniques (often called RESS2), where optimization is done both server-side and client-side, has become a trend. The recently launched WURFL.js3 tool, fits into this category.

In this article, we will look at some basic use cases of how to use WURFL.js to optimize the user experience both in HTML and CSS, and an example of how to choose the right ads to display on different devices. We will also see how WURFL.js is different from, but complements, the popular feature-detection library Modernizr.

Once Upon A Time, Device Detection

Whether we are using regular expressions in JavaScript, Modernizr or a complete device-description repository4 (DDR) for server-side detection, the purpose is usually the same: to give users a better experience. This typically happens at two levels:

  • presentation of content and interaction with the service,
  • analysis of user behavior to determine usage patterns.

The challenge is to do this in ways that are both scalable, maintainable and, as much as possible, easy to implement. For some projects, the cost and complexity of deploying third-party tools on servers is too high. Yet a low-maintenance solution that lets a website look good and perform well is possible, despite the constant diversification of devices. This is where WURFL.js plays a role, by providing a scalable alternative to traditional server-side device detection, all the while complementing other client-side techniques and tools.

Before diving in, let’s look at the basics.

Copy, Paste, Done

No registration is required, and WURFL.js can be used at no charge. So, the first thing to do is copy and paste this line of HTML into your page:

<script type='text/javascript' src=“//wurfl.io/wurfl.js"></script>

Both HTTP and HTTPS are supported. If you plan to use the device information provided by the script to make rendering decisions, then you might want to include the script in the <head> element. Otherwise, you can load it asynchronously.

Now that the script is in your HTML page, you can access the WURFL object in JavaScript. The WURFL object looks like this and is ready to use:

{
  complete_device_name:"Apple iPhone 5",
  form_factor:"Smartphone",
  is_mobile:true
}

The object has three properties:

  • complete_device_name
    This is the name by which the device is known — typically, the make and model or a category of devices or a more generic definition.
  • form_factor
    • desktop
    • app
    • tablet
    • smartphone
    • feature phone
    • smart TV
    • robot
    • other non-mobile
    • other mobile
  • is_mobile
    This is true or falsetrue if the device is a tablet or other mobile device.

Of course, you can immediately do things like this:

console.log(WURFL);

Or this:

alert(WURFL.complete_device_name);

Under The Hood

Because WURFL.js detects the device based on the User-Agent string and other information provided in the HTTP header, the contents of the JavaScript file will depend on the device. So, you can’t just copy the contents of the file and put it inline in the HTML or combine it with another JavaScript resource.

WURFL.js basic flow5
WURFL.js’ basic flow

To understand this in detail, let’s look at the illustration above. The browser makes a request for example.com (1). The markup returned by the Web server (2) contains the <script> reference to WURFL.js. Next, the browser renders the HTML and starts fetching assets — among them, wurfl.io/wurfl.js (3). When the request reaches WURFL.io, the HTTP request is analyzed by WURFL. Usually, based on that request, there will be an instant hit, and the device is identified without further ado, and a single WURFL JavaScript object is returned. However, in certain cases when the device cannot be identified on the server side alone (notably, in the case of iOS devices), the JavaScript file will contain a few more checks to determine the device. The browser then evaluates the JavaScript, and the WURFL object is ready to use (4).

WURFL.js is capable of, for example, distinguishing between an iPhone 5 and an iPhone 5S, thanks to this extra client-side logic. This is a big deal because this use case is supported neither by sheer User-Agent analysis6 nor by Modernizr tests.

A Note On Performance

If you use WURFL.js to make rendering decisions or, for some reason, you need to place the <script> tag inside <head> (without deferring it), then the browser will wait for the script to be downloaded and evaluated before rendering the page. Depending on the use case, this might be the only way; but, for the record, WURFL.js can also be loaded asynchronously to increase rendering performance.

The size of the returned JSON object will be fairly small, varying from 0.5 to 3 or 4 KB, depending on the device. Compared to Modernizr (about 14 KB) and jQuery (96 KB), WURFL.js is arguably light.

Use Cases

Assuming that you have WURFL.js up and running, let’s look at some cases in which using WURFL.js makes the most sense, either by itself or in conjunction with Modernizr and/or other solutions. To illustrate, we’ll refer to the WURFL.io website7 itself, which utilizes WURFL.js in multiple ways.

Optimizing the User Experience

When it comes to mobile, responsive and adaptive design and all that, the most common thing to do on a website is improve the user experience for certain device families or form factors. Much can be handled by media queries, of course, but sometimes you need the help of some JavaScript.

When you visit WURFL.io8 on your laptop, the top section of the page has a video background, some simple parallax scrolling and text that changes dynamically according to the device or browser. It looks very cool on a laptop, but video backgrounds, not to mention parallax scrolling, would not be ideal on a tablet or smartphone, to put it mildly.

Differences in presentation in desktop Safari and iPhone Safari9
Differences in presentation in desktop Safari and iPhone Safari.

We could use Modernizr, of course, or decide whether to implement these features in other ways. But in many cases, knowing the physical device is just as important as — perhaps more important than — knowing whether the browser claims support for a feature. We might encounter a problem whereby the browser claims support, but the support is actually not good enough to make a great user experience.

To avoid these situations, you would use WURFL.js and Modernizer together. Note also that comparing WURFL.js and Modernizr directly is not quite fair. Modernizr detects features claimed by the browser, whereas WURFL.js categorizes the device in different ways. So, if you don’t know whether a particular device or form factor supports a certain browser-detectable feature, then you are better off with Modernizr or a full-fledged device-detection solution10.

However, in this example, we’ll rely on WURFL.js and demand that only non-mobile clients get the video background and parallax scrolling:

/*video background*/
if(!WURFL.is_mobile){
  $('#vid').videoBG({
    mp4:'assets/Birds_Animation.mp4.mp4',
    ogv:'assets/Birds_Animation.oggtheora.ogv',
    webm:'assets/Birds_Animation.webmhd.webm'
  });
}

/*The parallax scrolling*/
window.onscroll = function () {
  if (!WURFL.is_mobile){
    heroImage.style[prefixedTransform] = "translate3d(0px," + window.scrollY / 2.3 + "px, 0px)";
    herovid.style[prefixedTransform] = "translate3d(0px," + window.scrollY / 1.1 + "px, 0px)";
    heroText.style["opacity"] = (1 - ((window.scrollY / 6) / 100));
  }
}

The example above simply checks whether the device is mobile (a phone or tablet) and introduces features accordingly. Of course, we could also leverage the more fine-grained WURFL.form_factor.

Put More In CSS?

The examples above show how to make use of the device’s data in JavaScript. However, we can make the device’s information available in CSS, too. We can assign different styles depending on the device, form factor and whether it is mobile. The first technique we will look at is similar to how Modernizr works. Modernizr adds a certain class to the HTML document depending on whether its test returns true or false.

Let’s say you want some specific behavior defined in the CSS for mobile devices. You would need to add the following JavaScript snippet to your page:

document.documentElement.className += ' ' + (WURFL.is_mobile ? '' : 'no-') + "mobile";

This will add a class to the html element. For mobile devices, it would say <html class=”is_mobile”>; for other devices, it would say <html class=”no-is_mobile”>.

If you know Modernizr, then you are probably familiar with this approach. Your CSS might take the following form:

.mobile #menu a{
  padding .5em;
}

.no-mobile #menu a{
  padding .1em;
}

In this simple example, we’ve increased the padding on menu items so that they are easy to tap with a fat thumb.

This method can be used for all of WURFL.js’ capabilities. However, because complete_device_name and form_factor are not boolean values (like is_mobile), the CSS part can become quite a headache. A bit more flexibility might come in handy, then. Here is an example using data- attributes:

document.documentElement.setAttribute('data-device_name', WURFL.complete_device_name);
document.documentElement.setAttribute('data-form_factor', WURFL.form_factor );

This will put data attributes with WURFL capabilities in the html element. We get several cool features with this method: We can target specific devices, form factors and even groups of devices combined with form factors by using CSS selectors:

html[data-form_factor = 'Smartphone'] #menu a{
  background: green;
}

Thanks to the wildcard attribute selector11 *, we can even match strings:

html[data-device_name*='Nokia'] [data-form_factor = 'Feature Phone'] {
  background: yellow;
}

The CSS above will match Nokia feature phones of any model. It also illustrates what the DOM looks like with the two methods implemented — in this case, with an iPhone 5S.

Help With Banner Ads

Many different ad networks are out there, each with its own specialization. Some are good for mobile, others for desktop. Some support text ads, other have ads of fixed size. If you are beyond a beginner’s level in ad networks, then you might want to assume some control over this. WURFL.js can help you make your own decisions or influence the network to make the right decisions for you.

The obvious approach is to ask WURFL.is_mobile to choose networks or ads that are good for mobile and others that are good for non-mobile.

if(WURFL.is_mobile){
  displayMobileAd();
}else{
  displayDesktopAd();
}

Moreover, from a design perspective, being able to fit the sizes and proportions of ads to your breakpoints and to design for different form factors of ads is nice. In the extreme, you could do something like this:

switch(WURFL.form_factor){
  case "Smartphone":
    if(WURFL.complete_device_name.indexOf("Apple") !=-1){
      showAppStoreAds();
    }else(
      showWebAds();
    )
    break;
  case "Tablet":
    showSpecificProportionAds();
    break;
  case "Feature Phone":
    showTextAds();
    break;
  default:
    showGoogleAdwords();
    break;
}

Conclusion

If you’ve tackled the diversity of devices in the past, then you’ll know that many developers have been looking for JavaScript tricks to detect browsers, devices and their respective features. Traditionally, a DDR required server-side libraries and data to be installed and for the device-description repository to be updated. WURFL.js is a freely available option to manage these issues.

You might want to consider WURFL.js or similar libraries for analytics, optimization of the user experience or advertising, and the library can complement Modernizr nicely. While Modernizr detects support for certain features of the browser, WURFL.js provides information about the user’s physical device.

WURFL.js is a bridge between the server side and the client side, making it easier for front-end Web developers to take advantage of functionality that used to belong on the server. It can also be used for current websites that have been designed responsively or that enhance progressively.

(al, il)

↑ Back to topShare on Twitter

Jon Arne is an active member and thought leader in the global mobile community since the late nineties. Jon Arne is a developer by trade, and truly believe that the key to success is a happy end user, and that innovative use of technology will help achieve that truly optimal user experience. Coding now is just done for recreation as he is now heading the Innovation team at ScientiaMobile.

Luca Passani is an Italian software engineer with many years of experience in Web and Mobile Internet development. Prior to co-founding his company, ScientiaMobile, Luca has worked for Openwave Systems, AdMob (now part of Google) and taken part in projects for Telecoms in the US and Europe. He is known to the community of developers for identifying the issues of device diversity (an area in which Luca is a recognized expert) as early as 1999. In 2001, Luca created WURFL, the Wireless Universal Resource FiLe, an Open-Source project that addressed the challenges of device fragmentation and established itself as the reference framework in the field.

  1. 1

    Based on the same problem we start to use browserclass.js, no special server side magic, it only puts the UA onto the html dom element. (But it can concat into your vendor scripts and cached)

    2
    • 2

      Hi there, article co-author here.

      WURFL.js is powered by a fully-fledged WURFL installation in the back-end, which means that the system will recognize devices and browsers (particularly mobile ones) that are not easily recognized with a single script. Anyway, the service is made available to the community of developers at no charge. If someone still prefers to have a local script, I am sure BrowserClass is a viable alternative. Thanks

      6
  2. 3

    Why does it use eval and a ofuscated code? At least it’s possible to can use a CORS proxy and parse the script.

    2
    • 4

      Hi Gustavo, the code is not really obfuscated, just minified for performance reasons. If you have specific questions about what those few lines of javascript code do, feel free to ask and we will answer.

      4
      • 5

        I recall there is a benefit to using http://dean.edwards.name/packer/ instead of gzip – smaller scripts compress better with packer and performace is better??? But I can’t remember exactly what… maybe you could remind me as it maybe useful for other readers/developers.

        Cheers,
        Dave

        -1
        • 6

          WURFL.js is built to support the mobile use case and assuming that gzip is supported on all devices/browsers seems a bit optimistic.

          0
  3. 7

    I think you do your readers a disservice by just blithely stating it is free to use and linking to the long and complex license, wherein you find the “gotcha” clauses about the service not being free to use on commercial sites that charge fees to use them. WURFL is a nice service but one thing it sure is not is cheap or free once you get into serious use!

    23
    • 8

      The service is offered at no cost, so how informing developers about its existence can be a “disservice” is beyond me (that’s unless someone is out on a killing spree just because server-side is involved, a “phenomenon” that has been observed a few times over the past few years).
      Also, I find it subtly dishonest to say the the license has gotchas. WURFL.js comes with a license that is absolutely comparable to the ones of services that people use every day and that nobody would think twice about adopting. Seriously, if you need to display a map, how many will walk into a library and scan a map with an expired copyright? and how many will plug into Google Maps through their APIs? same goes for many other similar free services offered by companies, big and small.
      The ironic part, in this discussion, is that internally in the company, I had to personally argue in favor of providing a free service, when others were asking: “why should we give WURFL away for free?” and the answer was: “because we want to be friends with developer and expose a tool that shows the power of server-side mobile optimization”.
      Anyone who has experience running a service in the Cloud knows that there needs to be a significant investment in development and maintainance resources. A credible service, including a free service, comes with a license. The license will protect the service provider against liability, but also ensure that resources are not abused with the purpose of safeguarding the service itself in the interest of all users. This is what our fine license does. Not more, not less.
      A company that sells mobile optimization as part of its commercial offering should license WURFL commercially for several reasons in addition to the terms of WURFL.js license, starting with the fact that they’ll need regular updates and a SLA of some kind that they can rely on to support their own customers.
      Anyway, at the end of the day, the overwhelming majority of websites out there can use the service at no cost. Many already do. If this cuts it for you, be our guest. If not, there are endless alternatives out there, each one with its pros and cons.

      5
      • 9

        Wasn’t saying it was a disservice to use the Smashing Magazine platform to promote your product, rather that just simply saying “free to use” is disingenuous when there is fine print in the license outlining a pretty big exception to that statement.

        I guess licensing is a bit of a hot button with WURFL’s history as a free open source project based on community-contributed data that was subsequently taken commercial. For all the talk of supporting developers, pricing for the commercial server-side solution that has nothing available for any price lower than $1500 (per year!) is not so developer-friendly.

        4
        • 10

          Here are a few key points for the record: WURFL provides value because ScientiaMobile provides a team that supports it. This requires a viable business model that was not possible with the previous more liberal licensing.

          The numbers you mentioned about the price of commercial licensing are misguided. WURFL can be a lot more expensive, but also a lot cheaper, depending on a variety of factors. The WURFL Cloud, for example, even comes with a free tier and remains pretty cheap also in the other tiers.

          The text has been changed to “No registration is required, and WURFL.js can be used at no charge.” Hope that makes you happy ;)

          -3
  4. 11

    Is it possible loading a different WordPress theme using WURFL.js?

    0
    • 12

      Thanks for your message. The way I understand wordpress is that the theme selection will need to happen in PHP, i.e. before the JavaScript has a chance to have its say, so the answer is probably no (unless unspeakable JS reload hacks are done, but I won’t even go there).

      Of course, theme selection can happen server-side with the classic PHP API or the WURFL Cloud (which also comes with a free “column” as you can see here http://www.scientiamobile.com/cloud).

      3
  5. 13

    How well does this technique play with Word Press server side caching plugins?

    0
    • 14

      Jon Arne Sæterås

      July 4, 2014 1:18 pm

      Should play well. The JavaScript is served from wurfl.io and not by WordPress. Wurfl.js file can be cached according to its HTTP cache directives, tho.

      0
  6. 15

    Where is the server side source code that I can set up my own wurfl server. I’m under the impression this is all open source right?

    0
    • 16

      Jon Arne Sæterås

      July 4, 2014 1:24 pm

      Well, wurfl.js is not open source. But WURFL is. To explore the open source offering go here: http://wurfl.sourceforge.net/
      So, WURFL has both a open source- and a commercial branch. Wurfl.js is built on the commercial branch but can still be used free of charge for most sites.

      0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top