detect and route with javascript

Alter width of article: Default / Full width

September, 1999.
By Molly E. Holzschlag. (Link to original article.)

"If happy users keep coming back, then you'll want to keep them happy by serving optimum pages to each site visitor and by keeping all the technical details under the hood. Find out how to choose or craft JavaScript sniff-and-route code that helps keep the user's experience an easy and pleasant one."

If happy users keep coming back, then you'll want to keep them happy by serving optimum pages to each site visitor and by keeping all the technical details under the hood. Find out how to choose or craft JavaScript sniff-and-route code that helps keep the user's experience an easy and pleasant one.

If you're like most developers, you're looking for ways to create a long-term relationship with your site visitors. One way to ensure user loyalty is to develop sites using client-side JavaScripts that seamlessly match a visitor's individual circumstances. With today's variety of browsers and platforms, differences in screen resolution, available plug-ins, and other technology, the challenge for the Web developer is to provide high-end sites that don't exclude lower-end visitors.

Serving user needs

Developers can rely on a variety of techniques to meet the needs of all anticipated users. The no-pain and no-gain approach: design to the lowest common-denominator user, restricting or leaving out technology that might cause problems for some visitors. Some sites list on the entry page which browsers and technologies are required to fully appreciate the Web site—with links so visitors can download any needed accoutrements.

Both those methods work, but they lack sophistication. When you can instead use JavaScript to detect what visitors need and route them to corresponding pages, why sell your users or your site short? Detect-and-route scripts can determine every visitor's browser and specs and direct the visitor to the set of pages that's most appropriate. Of course, the parallel sets of pages for different user levels means more planning and more work for the developer (namely you), but it also means a better user experience. Afterall, the developer's axiom is give them a good time on your Web site and they'll come back again.

Planning ahead

Before you do any scripting, it's important to understand both the intended audience for your site and the proposed content. You and your development team must carefully study any available demographic information and server statistics that will help you know what to expect of the target audience—the browsers, operating systems, monitor resolution, plug-in technologies they are likely to have, for instance. (See "The rock bottom lowest-common-denominator".) Then you can determine how to meet the needs of that audience by providing the best possible visual and technical experience. (See "Route for technology, not content".) Delivering the design and technology with consistency and clarity follows from there.

Understanding site content demands that you sit down with the client, organization, or colleagues involved and study the mission of the site. Having specific goals helps you to define what kind of options you will need to script. For example, if you anticipate a lot of Internet Explorer-centric DHTML on the site, but you need to support users without IE, you can plan for a script that routes non-IE users to a more accommodating page.

The rock-bottom lowest-common-denominator

As you study your audience statistics, you may find that some people you want to reach don't have JavaScript. They may be turning off JavaScript or using browsers that don't support it. Only about 3% of the total population of Web audiences don't use JavaScript, but it's an issue to keep your eye on. Of course, if it's essential to serve those users, you'll probably be designing alternative access pages for them, as that 3% probably can't process high-end pages anyway.

Once you've clarified the site intent and audience and made your basic design decisions, you can turn your mind to what kind of detect-and-route scripts you'll need. For instance:

Once you know what scripts you need, you decide whether to write your own or to adapt existing scripts (see Resources, below).

Route for technology, not content

There's a danger in assuming too much about your audience: you might assume incorrectly and cause user frustration. I have seen Web sites that put barriers around content with overambitious routing scripts. Consider the visitor who, using a Windows machine at work, is looking for information about the family's Macintosh computer at home. If, as the site developer, you assume that someone using a Windows machine wants only information about Windows, you're overstepping the line. Aim for serving your visitors, not tightly controlling their experience. Guide your visitors based on what they can support technically, rather than making guesses about what content they want.

Finding scripts or rolling your own

The choice to select prewritten scripts or develop your own really depends on your needs, your time, and your skills (or your team's). If there's something suitable out there that is freely available (see Resources, below), why reinvent the wheel? You can always adjust the existing scripts to meet your needs. On the other hand, if you have very specific requirements, you may need to custom code your detection scripts.

Next, I'll take you on a brief tour of detect-and-route scripts so you can get a taste of what these scripts can do for you.

Detecting the details

This detailed script demonstrates the kinds of information JavaScript can glean from behind-the-scenes. I'll break it down first so you can see how it works, then put it together in a usable format.

The script begins by detecting the Operating System and stores that information so it can be used later, as shown in Listing 1.

Listing 1. This part of the script grabs and stores the user's operating system.

var browserName = navigator.appName

var browserVersion = navigator.appVersion

var browserVersionNum = parseFloat(browserVersion)

var agt=navigator.userAgent

var yourOS="unknown"

if ((agt.indexOf("Win95")!=-1)||(agt.indexOf("Windows 95")!=-1))

{yourOS='Windows 95'}

if ((agt.indexOf("Win98")!=-1)||(agt.indexOf("Windows 98")!=-1))

{yourOS='Windows 98'}

if ((agt.indexOf("WinNT")!=-1)||(agt.indexOf("Windows NT")!=-1))

{yourOS='Windows NT'}

if ((agt.indexOf("Win16")!=-1)||(agt.indexOf("Windows 3.1")!=-1))

{yourOS='Windows 3.x'}

if (agt.indexOf("Macintosh")!=-1) {

if (agt.indexOf("PC)")!=-1) {yourOS='Mac PPC'} else {yourOS='Mac 68K'}

}

if (agt.indexOf("SunOS")!=-1) {yourOS='Unix Sun'}

if (agt.indexOf("IRIX")!=-1) {yourOS='Unix SGI'}

if (agt.indexOf("HP-UX")!=-1) {yourOS='Unix HP'}

if (agt.indexOf("AIX")!=-1) {yourOS='Unix IBM'; }

Listing 2. This part of the script assigns information from the browser to the script results.

var availheight="unknown"

var availwidth="unknown"

var bufferdepth="unknown"

var colordepth="unknown"

var height="unknown"

var width="unknown"

var javaOK = "unknown"

var cookiesOK = "unknown"

var minorVers = "unknown"

var cpu = "unknown"

var browsLang = "unknown"

Listing 3 collects additional information that's available only from 4.0 browsers. It's a sniff for more detailed information. (Cookies respond only to Internet Explorer 4.0 browsers and above, and the CPU test returns an unknown in Navigator.)

Listing 3. Collecting more information from version 4 of the browsers.

if (browserVersionNum >= 4) {

var availheight=screen.availHeight

var availwidth=screen.availWidth

var colordepth=screen.colorDepth + " bit"

var height=screen.height

var width=screen.width

if (navigator.javaEnabled()==true){javaOK="Yes"}

else{javaOK="No"}

//-- cookieEnabled only works in MSIE.

if (browserName=="Microsoft Internet Explorer") {

if (navigator.cookieEnabled==true) {

cookiesOK="Yes"

}else{

cookiesOK="No"

}

}

var cpu = navigator.cpuClass

}
vigator.cpuClass

}

To test the script, add the contents of Listing 4 to the body of an HTML document and then view the HTML document in a variety of browsers. I've included some HTML to make the resulting code attractive (and legible in the reduced image used in Figure 1 and Figure 2).

Listing 4. The detect and route script—in its entirety—within an HTML document.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<title>Basic Browser Detect</title>

<script language="JavaScript">

<!-- begin head script

var browserName = navigator.appName

var browserVersion = navigator.appVersion

var browserVersionNum = parseFloat(browserVersion)

var agt=navigator.userAgent

var yourOS="unknown"

if ((agt.indexOf("Win95")!=-1)||(agt.indexOf("Windows 95")!=-1))

{yourOS='Windows 95'}

if ((agt.indexOf("Win98")!=-1)||(agt.indexOf("Windows 98")!=-1))

{yourOS='Windows 98'}

if ((agt.indexOf("WinNT")!=-1)||(agt.indexOf("Windows NT")!=-1))

{yourOS='Windows NT'}

if ((agt.indexOf("Win16")!=-1)||(agt.indexOf("Windows 3.1")!=-1))

{yourOS='Windows 3.<i>x</i>'}

if (agt.indexOf("Macintosh")!=-1) {

if (agt.indexOf("PC)")!=-1) {yourOS='Mac PPC'} else {yourOS='Mac 68K'}

}

if (agt.indexOf("SunOS")!=-1) {yourOS='Unix Sun'}

if (agt.indexOf("IRIX")!=-1) {yourOS='Unix SGI'}

if (agt.indexOf("HP-UX")!=-1) {yourOS='Unix HP'}

if (agt.indexOf("AIX")!=-1) {yourOS='Unix IBM'; }

var availheight="unknown"

var availwidth="unknown"

var bufferdepth="unknown"

var colordepth="unknown"

var height="unknown"

var width="unknown"

var javaOK = "unknown"

var cookiesOK = "unknown"

var cpu = "unknown"

if (browserVersionNum >= 4) {

var availheight=screen.availHeight

var availwidth=screen.availWidth

var colordepth=screen.colorDepth + " bit"

var height=screen.height

var width=screen.width

if (navigator.javaEnabled()==true){javaOK="Yes"}else{javaOK="No"}

//-- cookieEnabled only works in MSIE.

if (browserName=="Microsoft Internet Explorer") {

if (navigator.cookieEnabled==true) {
cookiesOK="Yes"

}else{

cookiesOK="No"

}

}

var cpu = navigator.cpuClass

}

//-->

</script>

</head>

<body bgcolor="#cccc99" text="#000000" link="#993333" vlink="#cc9900" alink="#ffffcc">

<blockquote>

<h2>Detecting Browser, OS, Screen and Tech Info</h2>

<p>The JavaScript on this page sniffs information from the browser including platform, Java, cookies, screen resolution, color depth, and processor speed. We can also use JavaScript to reflect the information back to us as follows:

<p>

<script language="JavaScript">

document.write("Your browser is <b>"+ browserName +"</b><br>")

document.write("Your browser version is <b>"+ browserVersion +"</b><br>")

document.write("Your browser version number is <b>"+ browserVersionNum +"</b><br>")

document.write("Your platform is <b>"+ yourOS +"</b><br>")

document.write("Java Enabled?<b> "+ javaOK + "</b><br>")

document.write("Cookies Enabled?<b> "+ cookiesOK + "</b><br>")

document.write("Screen resolution: <b>"+width+" </b>x<b> "+height+"</b><br>")

document.write("Color depth: <b>" + colordepth + "</b><br>")

document.write("Available screen width: <b>" + availwidth + "</b><br>")

document.write("Available screen height: <b>" + availheight + "</b><br>")

document.write("CPU: <b>" + cpu + "</b></p>")

</script>

</blockquote>

</body>

</html>

Listing 5. The detect and route script—in its entirety—within an HTML document.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">

<html>

<head>

<title>Basic Browser Detect</title>

<script language="JavaScript">

<!-- begin head script

var browserName = navigator.appName

var browserVersion = navigator.appVersion

var browserVersionNum = parseFloat(browserVersion)

var agt=navigator.userAgent

var yourOS="unknown"

if ((agt.indexOf("Win95")!=-1)||(agt.indexOf("Windows 95")!=-1))

{yourOS='Windows 95'}

if ((agt.indexOf("Win98")!=-1)||(agt.indexOf("Windows 98")!=-1))

{yourOS='Windows 98'}

if ((agt.indexOf("WinNT")!=-1)||(agt.indexOf("Windows NT")!=-1))

{yourOS='Windows NT'}

if ((agt.indexOf("Win16")!=-1)||(agt.indexOf("Windows 3.1")!=-1))

{yourOS='Windows 3.<i>x</i>'}

if (agt.indexOf("Macintosh")!=-1) {

if (agt.indexOf("PC)")!=-1) {yourOS='Mac PPC'} else {yourOS='Mac 68K'}

}

if (agt.indexOf("SunOS")!=-1) {yourOS='Unix Sun'}

if (agt.indexOf("IRIX")!=-1) {yourOS='Unix SGI'}

if (agt.indexOf("HP-UX")!=-1) {yourOS='Unix HP'}

if (agt.indexOf("AIX")!=-1) {yourOS='Unix IBM'; }

var availheight="unknown"

var availwidth="unknown"

var bufferdepth="unknown"

var colordepth="unknown"

var height="unknown"

var width="unknown"

var javaOK = "unknown"

var cookiesOK = "unknown"

var cpu = "unknown"

if (browserVersionNum >= 4) {

var availheight=screen.availHeight

var availwidth=screen.availWidth

var colordepth=screen.colorDepth + " bit"

var height=screen.height

var width=screen.width

if (navigator.javaEnabled()==true){javaOK="Yes"}else{javaOK="No"}

//-- cookieEnabled only works in MSIE.

if (browserName=="Microsoft Internet Explorer") {

if (navigator.cookieEnabled==true) {
cookiesOK="Yes"

}else{

cookiesOK="No"

}

}

var cpu = navigator.cpuClass

}

//-->

</script>

</head>

<body bgcolor="#cccc99" text="#000000" link="#993333" vlink="#cc9900" alink="#ffffcc">

<blockquote>

<h2>Detecting Browser, OS, Screen and Tech Info</h2>

<p>The JavaScript on this page sniffs information from the browser including platform, Java, cookies, screen resolution, color depth, and processor speed. We can also use JavaScript to reflect the information back to us as follows:

<p>

<script language="JavaScript">

document.write("Your browser is <b>"+ browserName +"</b><br>")

document.write("Your browser version is <b>"+ browserVersion +"</b><br>")

document.write("Your browser version number is <b>"+ browserVersionNum +"</b><br>")

document.write("Your platform is <b>"+ yourOS +"</b><br>")

document.write("Java Enabled?<b> "+ javaOK + "</b><br>")

document.write("Cookies Enabled?<b> "+ cookiesOK + "</b><br>")

document.write("Screen resolution: <b>"+width+" </b>x<b> "+height+"</b><br>")

document.write("Color depth: <b>" + colordepth + "</b><br>")

document.write("Available screen width: <b>" + availwidth + "</b><br>")

document.write("Available screen height: <b>" + availheight + "</b><br>")

document.write("CPU: <b>" + cpu + "</b></p>")

</script>

</blockquote>

</body>

</html>

Figure 1 and Figure 2 show the results of using the script in Listing 4 and loading the page with Windows Internet Explorer 5.0 and Macintosh Netscape Navigator. The script demonstrates in detail the kind of information that can be detected using JavaScript.

Figure 1. This is what you see if you load the test page with Internet Explorer on a Windows 98 PC.

Figure 2. Compare the results of loading the test page with a Mac of recent vintage running Netscape Navigator.

Routing by browser type

One of the most common uses for these detection scripts is to route different pages for different browsers. The very simple script in Listing 6 sniffs for Netscape or Internet Explorer and allows you to redirect to a page specifically designed for one browser or the other. This makes it possible to use browser-specific technology when your audience would expect it without making other users feel left out.

Listing 6. This script routes users to pages you designed for their browsers.

<title>Easy Browser Detect-and-Route</title>
<SCRIPT LANGUAGE="JavaScript">
<!-- begin script
var ver = navigator.appVersion;
if (ver.indexOf("MSIE") != -1)
{
window.location.href="msie_index.html"
}else
window.location.href="nn.index.html"
// end script -->
</SCRIPT>
</head>
<body>

</body>
</html>

Here's how to make it work:

  1. Design a page for Netscape Navigator. In the example script, I've named it nn_index.html.
  2. Design a page for Internet Explorer. I've named it msie_index.html in the example script.
  3. Create an index page with the sniff-and-route script included, as shown in Listing 6. Leave the body of the index page empty.

When I loaded the index page of my sample site with Microsoft Internet Explorer, it sent me immediately to the IE page, shown in Figure 3.

Figure 3. Thanks to the script in Listing 6, the index page sent me to this page that fits the browser I used to test it.

Matching pages to display resolution

If you'd like to test and route for screen resolution, the script in Listing 7 does the trick. Of course, first you need to create pages for the different screen resolutions you plan to accommodate. You don't need to identify the resolution-specific pages by name—the script automatically handles that. Then create an empty HTML document with Listing 7 in the head portion.

Listing 7. This script tests for screen resolution and presents the correct pages for the browser's screen.

<SCRIPT LANGUAGE="JavaScript">
<!-- Begin
function redirectPage() {
var url640x480 = "http://www.yoursite.com/640x480";
var url800x600 = "http://www.yoursite.com/800x600";
var url1024x768 = "http://www.yoursite.com/1024x768";
if ((screen.width == 640) (screen.height == 480))
window.location.href= url640x480;
else if ((screen.width == 800) (screen.height == 600))
window.location.href= url800x600;
else if ((screen.width == 1024) (screen.height == 768))
window.location.href= url1024x768;
else window.location.href= url640x480;
}
// End -->
</SCRIPT>

In the opening body tag of the HTML document, add the following statement <body onload="redirectPage()">.

Save the page as a default or index page. Then test the script by changing your screen's resolution several times and reloading the page each time. Using this script, you can create designs optimized to the resolution dimensions of your audience.

Testing your scripts

Finally, it's important to deliver your scripts cleanly, and with consistency. Whether you write your own scripts or choose them from a library, test them vigorously in a variety of browsers and with several types of computers in order to ensure that they're working well.

Summing up

Undeniably, crafting extra sets of your site's pages customized for different users means more work and more time from you. Some developers decide—based on demographics and awareness of the site's intent—to forgo this extra step. Often that's a fair and reasonable choice. However, making a choice to use advanced technologies without thinking carefully about your audience is simply bad customer service. Using JavaScript detection and routing can help you serve your audiences well without compromising your design goals for high-end users, which leaves everyone holding a winning ticket.


Resources

Copyright Dunstan Orchard