Jump to Table of Contents

Cookie Utility

The YUI Cookie utility provides a simple API for interacting with cookies, including the creation and manipulation of subcookies.

Note about HTTPOnly Cookies: HTTPOnly cookies are cookies that may be set either by JavaScript or by the server but cannot be read from JavaScript. The YUI Cookie utility does not provide support for setting HTTPOnly cookies because browser support is not well-established and there is no fallback mechanism. Setting an HTTPOnly cookie on a browser that doesn't support it is the same as setting any other cookie (no error is thrown). When all A-grade browsers support setting HTTPOnly cookies by JavaScript, we will revisit adding support for it in the Cookie utility.

Getting Started

To include the source files for Cookie Utility and its dependencies, first load the YUI seed file if you haven't already loaded it.

<script src="http://yui.yahooapis.com/3.11.0/build/yui/yui-min.js"></script>

Next, create a new YUI instance for your application and populate it with the modules you need by specifying them as arguments to the YUI().use() method. YUI will automatically load any dependencies required by the modules you specify.

<script>
// Create a new YUI instance and populate it with the required modules.
YUI().use('cookie', function (Y) {
    // Cookie Utility is available and ready for use. Add implementation
    // code here.
});
</script>

For more information on creating YUI instances and on the use() method, see the documentation for the YUI Global Object.

Using the Cookie Utility

Creating Cookies

The simplest way to create a cookie is to provide a name and a value to the set() method:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y) {
    Y.Cookie.set("name", "value");
});

This example creates a cookie called "name" that has a value of "value". Since this cookie is created with all of the default settings, it becomes a session cookie.

There is a third argument for set(), which is an object containing additional settings for the cookie. To create a persistent cookie, you can specify an expiration date by supplying a Date object:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y) {
    Y.Cookie.set("name", "value", { expires: new Date("January 12, 2025") });
});

By providing an "expires" option in the third argument, the cookie persists until the given date. In this example, the cookie will remain until January 12, 2025. The value for "expires" must be a Date object, otherwise it is ignored.

It's possible to restrict access to a cookie by setting path and/or domain information. Setting a path on the cookie restricts access to pages that match that path; setting a domain restricts access to pages on a given domain (typically used to allow cookie access across subdomains). Both options can be easily set using the "path" and "domain" options:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y) {
    Y.Cookie.set("name", "value", {
        path: "/",           //all pages
        domain: "yahoo.com"   //any subdomain of yahoo.com, including www.yahoo.com
    });
});

In this example, a cookie is created that can be accessed from all pages on a yahoo.com subdomain. This cookie would then be accessible from pages on sports.yahoo.com as well as www.yahoo.com. The "path" and "domain" options need not be used together; they may be used independently as well.

The last option is "secure", which indicates that the cookie should only be accessible via SSL on a page using the HTTPS protocol. All other aspects of the cookie remain the same based on the other options provided. To set a secure cookie, use the "secure" option:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    Y.Cookie.set("name", "value", { secure: true });
});

This code creates a secure cookie by setting the "secure" option to true. Note that this will only work if the page calling this code uses the HTTPS protocol, otherwise the cookie will be created with default options.

There is one more option called "raw". When this option is specified, the cookie will not be URL-encoded before being set. Setting a "raw" cookie typically means that you have specialized server-side logic to deal with cookies that aren't URL-encoded. This is considered an advanced option that should only be used when necessary. Example usage:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    Y.Cookie.set("name", "value", { raw: true });
});

Reading Cookies

The get() method retrieves cookies that are accessible by the current page. If a cookie doesn't exist, get() returns null.

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    var value = Y.Cookie.get("name");
});

This example retrieves the cookie called "name" and stores its value in the variable value. By default, values returned by get() are strings (if the cookie exists) or null (if the cookie doesn't exist). You can change the return value by providing a conversion function as the second argument. For example, to return a number, you can pass in the native Number() function:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    var value = Y.Cookie.get("age", Number);
});

In this code, the returned cookie value will be a number if the cookie exists (it will still be null if the cookie doesn't exist). Other native functions that convert values are Boolean() and Date, or you can define your own conversion function:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    var value = Y.Cookie.get("code", function(stringValue){
        return parseInt(stringValue, 16);   // Create a number from a hexadecimal code
    });
});

Conversion functions accept a single argument, the string value of the cookie, and must return a value. In this example, the conversion function expects a hexadecimal code to be returned and passes it into parseInt() to convert the value into a number. Note that the conversion function is never called if the cookie doesn't exist (get() always returns null when the cookie doesn't exist).

The second argument can optionally be an object if you'd like to read a raw cookie. As with, writing cookies, it's possible to read a cookie without URL-decoding the value. To specify this, the second argument should be an object, such as:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    var value = Y.Cookie.get("code", { raw: true });
});

If you'd like to use a converter on a raw cookie, you can specify this using the "converter" option:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    var value = Y.Cookie.get("code", {
        raw: true,
        converter: function(stringValue){
            return parseInt(stringValue, 16);   // Create a number from a hexadecimal code
        }
    });
});

Deleting Cookies

When a cookie is no longer need, it can be removed from the browser by calling the remove() method. This method takes two arguments: the name of the cookie to remove and an optional cookie options object. A cookie created with specific options can only be deleted by specifying the same options. For instance, a cookie created with a domain property of "yahoo.com" can only be deleted by also specifying the domain property as "yahoo.com". Examples:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){
    //delete the cookie named "code"
    Y.Cookie.remove("code");

    //delete the cookie named "info" on the "yahoo.com" domain
    Y.Cookie.remove("info", { domain: "yahoo.com" });

    //delete a secure cookie named "username"
    Y.Cookie.remove("username", { secure: true });                    
});

Subcookies

Each browser has a limit to the number of cookies that can be set per domain. These limits can be problematic for domains with different sites under different subdomains. Since cookie name-value pairs are rarely large enough to reach the byte limit for an individual cookie, it represents an opportunity to store multiple name-value pairs in a single cookie; these are called subcookies.

A subcookie string looks similar to a URL and takes the following form:

cookiename=name1=value1&name2=value2&name3=value3

The Cookie utility supports this style of subcookies to allow multiple values to be stored in a single cookie. To set a subcookie value, use the setSub() method. This method accepts four arguments: the cookie name, the subcookie name, the subcookie value, and an optional options object. Note that the options object works on the entire cookie, it is not specific to the subcookie.

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    //set a cookie named "name" with a subcookie named "subname" whose value is "value"
    Y.Cookie.setSub("name", "subname", "value");

    //set a second subcookie on "name", with a name of "subname2" and a value of "value2"
    Y.Cookie.setSub("name", "subname2", "value2");

    //set subcookie on the "yahoo.com" domain
    Y.Cookie.setSub("info", "age", 22, { domain: "yahoo.com" });

    //set subcookie to a secure cookie named "user"
    Y.Cookie.setSub("user", "name", "ace123", { secure:true });                        
});

It's possible to set the entire contents of a subcookie by using the setSubs() method, which accepts three arguments: the name of the cookie, and object containing name-value pairs, and an optional cookie options object. For instance, this code sets three subcookies at once:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    var data = {
        name: "ace123",
        age: 22,
        track: true
    };                    

    //set a cookie named "user" with subcookies
    Y.Cookie.setSubs("user", data);

});

Note that calls to setSubs() will always completely overwrite the cookie.

To retrieve subcookie values, there are two methods. The first is getSub(), which retrieves a single subcookie value. This method accepts three arguments: the cookie name, the subcookie name, and an optional converter function. As with get(), the converter function changes the data or type of data retrieved from the cookie before it's returned (and isn't called at all if the cookie or subcookie doesn't exist):

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    //get subcookie
    var stringValue = Y.Cookie.getSub("name", "subname");

    //get subcookie and convert to number
    var numberValue = Y.Cookie.getSub("user", "age", Number);

    //get subcookie and convert from hex code to decimal number
    var integerValue = Y.Cookie.getSub("settings", "bgcolor", function(stringValue){
        return parseInt(stringValue, 16);   // Create a number from a hexadecimal code
    });
    
});

The second method to retrieve subcookies is getSubs(), which retrieves all subcookies and returns an object with name-value pairs for each subcookie. The getSubs() method takes a single argument, the name of the cookie containing subcookies to retrieve. The returned value is either an object or null if the cookie doesn't exist.

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    //get all subcookies
    var data = Y.Cookie.getSubs("name");
    var subValue = data.subname;

    //get all subcookies
    var user = Y.Cookie.getSubs("user");
    var userName = user.name;
    
});

Removing subcookies is accomplished using the removeSub() method. This method accepts three arguments: the cookie name, the subcookie name, and an optional cookie options object. The options object, if specified, must have the same options as when the cookie was originally created. Example:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    //set subcookie on the "yahoo.com" domain
    Y.Cookie.setSub("info", "age", 22, { domain: "yahoo.com" });

    //remove the subcookie
    Y.Cookie.removeSub("info", "age", { domain: "yahoo.com" });                        
});

Removing a subcookie keeps all other subcookies for that cookie intact. If you want to remove all subcookies, it's easiest to use remove() to remove the entire cookie.

When the last subcookie is removed, the overall cookie still remains. If you'd like to remove the cookie when the last subcookie is removed, then specify the "removeIfEmpty" option:

// Create a YUI instance and use the cookie module.
YUI().use('cookie', function(Y){

    //remove the subcookie
    Y.Cookie.removeSub("info", "age", { removeIfEmpty: true });                        
});