Menu Search
Jump to the content X X
SmashingConf London Avatar

We use ad-blockers as well, you know. We gotta keep those servers running though. Did you know that we publish useful books and run friendly conferences — crafted for pros like yourself? E.g. our upcoming SmashingConf London, dedicated to all things web performance.

Server-Side Device Detection With JavaScript

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.

Further Reading on SmashingMag:

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 Link

Whether we are using regular expressions in JavaScript, Modernizr or a complete device-description repository7 (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 Link

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=“//"></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",

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:


Or this:


Under The Hood Link

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 flow8

WURFL.js’ basic flow

To understand this in detail, let’s look at the illustration above. The browser makes a request for (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, (3). When the request reaches, 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 analysis9 nor by Modernizr tests.

A Note On Performance Link

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 Link

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 website10 itself, which utilizes WURFL.js in multiple ways.

Optimizing the User Experience Link

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.io11 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 Safari12

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 solution13.

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*/

/*The parallax scrolling*/
window.onscroll = function () {
  if (!WURFL.is_mobile){[prefixedTransform] = "translate3d(0px," + window.scrollY / 2.3 + "px, 0px)";[prefixedTransform] = "translate3d(0px," + window.scrollY / 1.1 + "px, 0px)";["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? Link

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 selector14 *, 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 Link

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.


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:

  case "Smartphone":
    if(WURFL.complete_device_name.indexOf("Apple") !=-1){
  case "Tablet":
  case "Feature Phone":

Conclusion Link

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)

Footnotes Link

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
  12. 12
  13. 13
  14. 14

↑ Back to top Tweet itShare on Facebook

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

    Peter Marosi

    July 1, 2014 4:43 pm

    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

      Luca Passani

      July 1, 2014 6:04 pm

      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

  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.

    • 4

      Luca Passani

      July 1, 2014 6:05 pm

      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.

      • 5

        I recall there is a benefit to using 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.


        • 6

          Luca Passani

          July 3, 2014 12:27 am

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

  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!

    • 8

      Luca Passani

      July 2, 2014 11:14 am

      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.

      • 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.

        • 10

          Luca Passani

          July 3, 2014 8:49 am

          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 ;)

        • 11

          So this was an opensource project that’s effectively been hijacked, and charges $1500/year for commercial use?!

          And this bozo is still claiming it’s free to use…

          • 12

            Luca Passani

            July 16, 2014 8:44 am

            Nothing has been hjacked. ScientiaMobile owns the copyright of WURFL (API and data collection). API previously released as open source are still open source with their respective licenses.
            Offending people anonymously on the internet? that’s a bozo behavior.

  4. 13

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

    • 14

      Luca Passani

      July 2, 2014 11:19 am

      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

  5. 15

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

    • 16

      Jon Arne Sæterås

      July 4, 2014 1:18 pm

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

      • 17

        So the output can be cached and served up to multiple users even if the wurfl request has to be made on every request of my wordpress site?

        • 18

          Jon Arne Sæterås

          July 7, 2014 2:48 pm

          Hi Tom.
          The actual contents of wurfl.js will vary depending on user-agent. A given user with a given device will of course get the same JSON object every time. This object is cached in a cookie.
          If your question is whether you can cache that info (map a user-agent to properties and cache that in a file on your server), locally, we cant recommend that as updates to the device data happen frequently enough that this strategy may backfire.

  6. 19

    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?

    • 20

      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:
      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.

  7. 21

    Obinwanne Hill

    July 5, 2014 6:27 am

    Actually, I’m getting a 403 Forbidden page when I visit Hopefully you can fix that soon.

    A few questions/comments:

    1. I really don’t believe Server-Side is the best way to deal with this challenge. It’s much faster when done on the Client-Side, except where you need super-granularity like the device brand name. From the simple sequence diagram you highlighted it seems like everything has to go through Does this happen each time a page is loaded? How long does that roundtrip process take per user request on average? If my website using wurfl.js is visited my 1 million unique users, does get hit with 1 million requests?!

    2. Your Note on Performance doesn’t provide any definitive note on performance. How does your approach stack up against media queries, or other mobile website design and development methods when using metrics from, say,! Performance isn’t just about smaller file sizes, you know.

    3. I like the granularity of the solution, but this just seems to point to an even more complex workflow for Web designers. It just seems like this could turn out to be more work building websites on a device name level e.g. Nokia, HTC, Xiaomi, etc. as opposed to device class e.g. phone, tablet, etc., even with regards to serving ads?!

    4. How come you went with CSS attribute selectors? It seems to me that class selectors would be the better, more terse way to go. You mention that ‘complete_device_name’ and ‘form_factor’ are not booleans, but they kind of are being that a Nokia phone can’t be a HTC phone, just like a Smartphone can’t be a Tablet?!

    5. I do find your assertion of Wurfl.js being free a tad misleading as some other commenter has highlighted. A lot of designers build websites for clients that very well could be using them for commercial reasons. Saying it’s “free to use” only for them to find out later that there’s a catch will alienate designers/developers. I have nothing against you making a living, but it’s good to be clear from the onset.

    I recently developed a plugin called Restive.JS ( that is Client-Side, free, open-source, and has a few more designer features than WURFL like Orientation Support and Modularity. I’d be more than happy to do a comparison with you guys for the benefit of SmashingMag readers and the Web community.

    • 22

      Luca Passani

      July 6, 2014 5:32 pm

      The webpage had a hickup on saturday morning european time, but it was promptly restored (Amazon removed one of our services and the automated mechanism to reinstate a new one had a glitch that has now been addressed). The service itself had no disruption at all (as an aside, I provide this information just in case someone suspects that running a service in the Cloud is just a matter of placing a server online and forget about it).

      Coming to your points:

      1. has been designed to integrate with Responsive Web Design in mind. It integrates smoothly and augments RWD. It enables a variety of RESS optimizations which are hard or impossible to achieve with a pure client side approach. This is particularly true when used in conjuunction with WIT, the Image Tailor that will resize your images server-side. The returned WURFL data (typically very small) is a single unique request, so I wouldn’t characterize it as “everything has to go through”. It does not. Performance is nothing short of very fast. If one uses jQuery, bootstrap, angular (or even just images, and complex CSS), the bottlnecks are going to be found elsewhere. Finally, if your website gets hit with 1 million requests, that’s good for you. It does not make a difference from, which can manage that load (and way more) quite easily and already does today without missing a beat.

      2. the speed with which the JSON file is served is good enough (under 100 milliseconds typically). Once the website has the JSON object, what JavaScript does with that information is no longer a problem. If you use that info for heavy DOM manipulation, that’s where the bulk of the work is going to happen for the browser, no matter if one uses WURFL.js or not.

      3. WURFL.js does NOT mandate that one codes for single devices or device family. WURFL.js simply aims at being a tool in the toolbox of web programmers. If a front-end developer needs to address specific mobile devices or device families, WURFL.js might be the way to go.

      4. I think you are misunderstanding the purpose of the example. The example simply shows what can be done. It does not mandate a way to do it. Once you have the JSON object, you can do pretty much whatever you want with it with whatever combined CSS-JS wizardry one is capable of.

      5. I am not sure how to address the point of the license any better than I have already done. I see GoogleMaps being used everywhere and people saying “thank you, Google” for this. Yet, the licenses of WURFL.js and GMpas are identical from this viewpoint (you are not allowed to use Maps in commercial applications). You can use the service on pretty much any website, including websites of commercial companies, but not as part of a web-based service that requires a paid subscriptions. The point with not using commercially is mostly meant at ensuring that people who need a commercial-grade SLA do not assume that the SLA provided by WURFL.js Community Edition is good enough to be transfered to their commercial customers. As I wrote in one of my previous comments, I have asked Smashing Magazine to reword this as “can be used at no cost”, which should make the nitpickers happy.

      Finally, I am happy to hear that you have also developed a free tool for developers. I am sure that you can write a nice article and submit it to Smashing Magazine for review and publication.

      Thank you

  8. 23

    This is a great service but…. I use it now for one week and severall times my sites hangs because of the loading of the js file. Looks like this is not mature and cannot be used because of these loading problems

    • 24

      Luca Passani

      August 1, 2014 3:35 pm

      Thank you for your message, Cesar.

      In all openess, you are right about th fact that there were a couple of hiccups in the WURFL.js service. The reality is that adoption of the service has grown to several tens of millions of requests per day over the past month or so. We have solid system monitoring that will notify about the health of, and automatically restart servers and create new ones when capacity is reached. In a couple of occasions the system has been overwhelmed by the spike of usage or by issues with AWS, but you can trust us that each of those occasions has served the purpose of beefining up the infrastracture: deployment of extra capacity and extra auto-recovery mechanisms. In short, please bear with us. You won’t be disappointed.

  9. 25

    Christo Romberg

    January 2, 2015 1:38 pm

    Thank you for this article, very insightful.

    I personally use and love Dave Molsen’s Detector library, it is very dynamic and learns new devices automatically.


↑ Back to top