Make Client Side Data Available Server Side

Published by Chris Coyier

UPDATE: I have a newer article "Server Side Mustard Cut" that covers this same ground and has many of the quirks worked out. That's probably a better read.

That would be pretty useful, right? Right now it's very common to User Agent "sniff" when you want to make a server-side decision about what to give the client. But UA sniffing has always sucked and sucks more every day. What you really want to know is stuff like "how big is the screen I'm serving to?" or "does the device I'm serving to have touch events?" - that way you can serve resources that are appropriate to those questions. Is there a way to get accurate client side information on the server side?

Why Server Side?

You might want to serve an entirely different layout or different part of a layout if you know (for sure) you are serving to a small mobile device. Or a TV. Or whatever. See this article.

Put the Data in a Cookie

I think the easiest way to make client side information available server side is by putting that data in a cookie. Cookies are sent in the headers of all requests to that domain, so the server has access to them. If that cookie has information in it about how big the browser window is, the server can use it.

Cookie Logic

In order to make the smart choices you want to make, you need this cookie to exist. If it does exist, cool. If it doesn't exist, do the bare minimum you need to do to client test, set the cookie, then refresh.

In PHP, just to illustrate:

<?php if isset(($_COOKIE['_clientInfo'])) { ?>

   <p>You have the cookie, so put in your logical stuff here and load the document as you will.</p>

<?php } else { ?>

   <p>You don't have the cookie yet, so don't load anything but the resources you need to test the client and set the cookie. Then refresh.</p>

<?php } ?>

Setting the Cookie

What kind of information might you want? Screen size likely. Probably anything that Modernizr would be able to tell you.

It's easy to set a cookie in JavaScript.

document.cookie = "cookieName=" + value;

Make the value easy for you to parse and do what you need with. Here let's make it a string of JSON. We'll make an object with all the data we want and use some jQuery and Modernizr to get the values we want to know.

var clientInfo = {
  browserWidth: $(window).width(),
  browserHeight: $(window).height(),
  flexboxSupport: Modernizr.flexbox,
  SVGSupport: Modernizr.svg
};

document.cookie = "_clientInfo=" + JSON.stringify(clientInfo);

In testing, I had some issues with Opera so switched to the jQuery cookie plugin and it was fine.

var cookieVal = JSON.stringify(clientInfo);

$.cookie("_clientInfo", cookieVal, {
  expires: 7
});

Refresh After Setting the Cookie

Now that the cookie is set, you can refresh the page so the document can actually load with all this juicy information available.

window.location.reload();

NOTE: refreshing is a bit tricky though, please read this.

Jank Alert?

If you don't like the idea of refreshing, you could write it up so you load some kind of default document at the same time you are setting the cookie. No harm there.

How Long Should the Cookie Last?

I dunno. An hour maybe? Forever? There is some chance that you catch somebody when their desktop browser is in an unusual state. Like they have it super small, and they load your page, and they then get a small screen version forever. Or an update to that browser comes out with more advanced features but your old cookie is there. Your call.

Here's an example of one hour:

var now = new Date();
var time = now.getTime();
time += 3600 * 1000; // one hour
now.setTime(time);

document.cookie = "_clientInfo=" + JSON.stringify(clientInfo) + ";expires=" + now.toGMTString();

Using the Info Server Side

Using PHP just as an example, you can easily snag the cookie and access bits of the data we saved as JSON.

<?php
  $json = $_COOKIE['_clientInfo'];
  $obj = json_decode(stripslashes($json));
  echo "<p>Browser Width: " . $obj->{'browserWidth'} . "</p>";
?>

You wouldn't just echo it out like above, you'd use some logic on that data and do whatever fancy special serving of resources and content you are going to do.

Using the Info Client Side

The point of this is server-side access, but, you have access to that cookie on the client-side too. This means, theoretically, you wouldn't need to load Modernizr again because you already have that information.

Here's a simple example that gets the data and displays a part of it:

var clientInfo = JSON.parse("<?php echo $_COOKIE['_clientInfo']; ?>");
var output = "<p>Browser Width: " + clientInfo.browserWidth + "</p>";
$("#clientInfo").append(output);

Demo

World's simplest demo just to show it's do-able.

Downsides?

I dunno. I suspect there are a bunch otherwise I would think this kind of thing would be done more often. Smart people: chime in in the comments and let me know the ups and downs.

I suspect it might complicate caching. Perhaps that much reading/sending of the cookie is an issue? What about people that don't allow cookies like this? Gotta make sure they don't get in any kind of infinite loop or have the site be unusable.

Other Things

  • The first I heard of this kind of thing being used was in Matt Wilcox's Adaptive Images where the screen resolution is saved as a cookie and used to make choices about what kind of images to use.
  • Client-Hints is also a thing that aims to give us this information without all this fancy dancing.
  • James Pearce's modernizr-server:

    The modernizr-server library is a way to bring Modernizr browser data to your server scripting environment.

  • Dave Molsen's Detector:

    Detector is a simple, PHP- and JavaScript-based browser- and feature-detection library that can adapt to new devices & browsers on its own without the need to pull from a central database of browser information.

  • Shane Gliser talks about doing this but saving to HTML5 localstorage in his book Creating Mobile Apps with jQuery Mobile