---
title: Super Easy Responsive Images with Viewport Cookies
date: 2012-06-12T22:24:10+00:00
modified: 2012-06-12T22:48:31+00:00
image:: https://kaspars.net/wp-content/uploads/2012/06/viewport-cookies-adaptive-images-wordpress.jpg
permalink: https://kaspars.net/blog/adaptive-images-viewport-cookies
post_type: post
author:
  name: Kaspars
  avatar: https://reverse.kaspars.net/gravatar/avatar/92bfcd3a8c3a21a033a6484d32c25a40b113ec6891f674336081513d5c98ef76?s=96&d=mm&r=g
post_tag:
  - How to
  - Nginx
  - Snippet
category:
  - Web Performance
  - WordPress
---

# Super Easy Responsive Images with Viewport Cookies

Here is the idea behind the **Viewport Cookies**:

1. first, detect the width of the device viewport using javascript and store its value in **a `viewport` cookie** from within the `<head>`;
2. use that cookie in the backend (with Nginx `image_filter` or a PHP script) to resize, cache and serve images of appropriate size for that particular viewport.

The great thing about this method is that it doesn’t require any modifications to the image tags and the javascript is kept to the bare minimum.

![Adaptive Images with Viewport Cookies](https://kaspars.net/wp-content/uploads/2012/06/viewport-cookies-adaptive-images-wordpress.jpg?strip=all&quality=90&resize=500,245 "Adaptive Images with Viewport Cookies")

### Part 1: Store the Screen Width in a Cookie Using Javascript

Javascript is the only thing that can detect parameters such as browser window dimensions and device screen size, so we have to use javascript until (and if) browsers start setting this data in HTTP request headers.

Cookies, however, are the only dynamic thing that can be passed together with the request to the backend without changing the request URL. So we use them both to first choose an optimal reduced image width and then store it into a cookie called `viewport` which the browser will send along **all the subsequent requests**, including for the images.

Keep in mind that cookies are set per domain name and in case you’re of using a Content Delivery Nework for serving static assets you will have to set the `viewport` cookie **from the CDN**.

```
<script type="text/javascript">
	if (screen.width < 1000) 
		viewport = 800; 
	if (screen.width < 800) 
		viewport = 600; 
	if (screen.width < 450) 
		viewport = 400; 

	if (typeof viewport != 'undefined') 
		document.cookie = 'viewport=' + viewport;
</script>
```

You can use whatever logic and levels of adaptiveness you want, but keep in mind that not setting a viewport cookie for larger screens will save you cache hits.

Here is a simple filter for WordPress that will put it into your theme’s `<head>`:

```
add_action( 'wp_head', 'add_viewport_cookie_js' );

function add_viewport_cookie_js() {
?>
	<script type="text/javascript">
		if (screen.width < 1000) viewport = 800; if (screen.width < 800) viewport = 600; if (screen.width < 450) viewport = 400; if (viewport) document.cookie = 'viewport=' + viewport;
	</script>	
<?php
}
```

### Part 2: Use the Viewport Cookie Value to Serve Resized Images

Once the cookie is set, it will be passed along all the subsequent requests, including for images, so we just read it’s value in the backend and resize the image accordingly. Here is an example of how to do it in Nginx:

```
location ~ \.(jpg|jpeg|gif|png)$ {
	expires max;

	# Resize only if a valid cookie value is present
	if ( $cookie_viewport ~ ^800|600|400$ ) {
		return 418;
	}

	error_page 418 = @viewport_image;
}

location @viewport_image {
	internal;

	expires max;
	add_header X-Viewport $cookie_viewport;

	image_filter   resize $cookie_viewport -;
	image_filter_jpeg_quality 90;

	error_page     415   = /empty;
}

location = /empty {
	internal;
	empty_gif;
}
```

In the first location block that captures all images we simply add a new check for a valid value of the viewport cookie. If a valid cookie is present, we send the request to an internal virtual location called `@viewport_images` which uses the built-in `image_filter` function of Nginx to resize the image accordingly. Notice that we are specifying only the width of the image while the height is set to `-`, which means that it will be scaled proportionally.

We also add a custom HTTP header called `X-Viewport` to make it easier to verify the viewport size that was used in the backend (via the Network tab in Developers Tools, for example).

### Conclusion

Viewport Cookies is an extremely simple method for serving images of reduced dimension and file size to devices and browser that can display only a certain amount of pixels. Although the screen size of a device doesn’t necessarily mean that it has a slow network connection (like when using iPad on a WiFi network vs GPRS), it is still beneficial to browser that have screens smaller than SVGA (800 x 600).