Create custom cookie in JavaScript

Create your custom cookie that is available on the document object with the only max-age option.

Example

document.myCookie = "blog=learnersbucket";
document.myCookie = "name=prashant;max-age=1"; // this will expire after 1 second

console.log(document.myCookie);
// "blog=learnersbucket; name=prashant"

setTimeout(() => {
  console.log(document.myCookie);
}, 1500);
// "name=prashant" is expired after 1 second
// "blog=learnersbucket"

As our custom cookie is available on the document object, we will extend the document using Object.defineProperty() and add the custom property "myCookie", this will give us the additional methods like get() and set() that could be used behind the scene to make the cookie entry and return it.

To implement this, we will create a function with a map() to persist the entry of each cookie.

  • As the cookie string is colon separated values with data and options, in the set() method we will extract the data and separate it on the key and value and also the options (max-age) and store them in the map.
  • While getting the cookie, get all the entries of the map and for each entry check if it has expired or not. If it is expired, delete the entry. Send the remaining entry as a string with a colon-separated.

To parse the input and separate the data and options, we will be using a helper function.

// helper function to parse the
// key-value pairs
function parseCookieString(str) {
  // split the string on ;
  // separate the data and the options
  const [nameValue, ...rest] = str.split(';');
  
  // get the key value separated from the data
  const [key, value] = separateKeyValue(nameValue);
  
  // parse all the options and store it
  // like max-age
  const options = {};
  for(const option of rest) {
    const [key, value] = separateKeyValue(option);
    options[key] = value;
  }
  
  return {
    key,
    value,
    options,
  }
}

// helper function
// to separate key and value
function separateKeyValue(str) {
  return str.split('=').map(s => s.trim());
}

For the main logic we can extend the document object with Object.defineProperty().

// enable myCookie
function useCustomCookie() {
  
  // to store the key and value
  // of each cookie
  const store = new Map();

  Object.defineProperty(document, 'myCookie', {
    configurable: true,
    get() {
      
      const cookies = []; 
      const time = Date.now();
      
      // get all the entries from the store
      for(const [name, { value, expires }] of store) {
        // if the entry is expired
        // remove it from the store
        if (expires <= time) {
          store.delete(name);
        } 
        // else push the key-value pair in the cookies array
        else {
          cookies.push(`${name}=${value}`);
        }
      }
      
      // return all the key-value pairs as a string
      return cookies.join('; ');
    },

    set(val) {
      // get the key value of the data
      // and option from the string
      const { key, value, options } = parseCookieString(val);
      
      // if option has max-age
      // set the expiry date
      let expires = Infinity;
      if(options["max-age"]) {
        expires = Date.now() + Number(options["max-age"]) * 1000;
      }
      
      // add the entry in the store
      store.set(key, { value, expires });
    }
  })
}
Input:
useCustomCookie();
document.myCookie = "blog=learnersbucket";

// this will expire after 1 second
document.myCookie = "name=prashant;max-age=1"; 

console.log(document.myCookie);

setTimeout(() => {
  console.log(document.myCookie);
}, 1500);

Output:
"blog=learnersbucket; name=prashant"
"blog=learnersbucket"