DEV Community

Cover image for Efficient Cookie Management with the Cookie Store API
Peter Mbanugo
Peter Mbanugo

Posted on • Originally published at pmbanugo.me

5 3 2 3 2

Efficient Cookie Management with the Cookie Store API

The browser Cookie Store API represents a modern approach to handling cookies in web applications. The way we’ve always done it is using document.cookie which is error-prone because you have to work with key/value pairs in a string. Besides being error-prone, it’s a synchronous, blocking operation, which doesn’t fit modern patterns whereby we try to move certain operations to be asynchronous and out of the main thread. It depends on the document object, therefore it can’t be used in a Service Worker context.

This tutorial explores how this new API simplifies cookie management. We’ll build a site with light and dark themes, allowing users to switch themes and store their preferences in a cookie for future visits.

Understanding Cookie Management: Then and Now

Traditionally, web developers have used the document.cookie API to work with cookies. Here's how we used to handle cookies:

// Setting a cookie
document.cookie = "theme=dark; expires=Fri, 31 Dec 2024 23:59:59 GMT; path=/";

// Reading cookies
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(";").shift();
}

// Using the cookie
const theme = getCookie("theme");
if (theme === "dark") {
  document.body.classList.add("dark-theme");
}
Enter fullscreen mode Exit fullscreen mode

At first glance, setting cookies with document.cookie feels like we're overwriting the entire cookie value. The string manipulation needed to read a cookie value is cumbersome, and a small mistake can break your application. Handling multiple cookies means parsing the cookie string over and over, and due to its synchronous nature, this could slow down your application.

The Cookie Store API on the other hand addresses those issues by providing a promise-based interface with these advantages:

  • Cleaner, more intuitive methods for reading and writing cookies
  • Built-in event handling for cookie changes
  • Asynchronous operations that don't block the main thread
  • Methods to handle multiple cookies efficiently

Building a Theme Switcher with Cookie Store API

Let's see how to build a theme switcher that demonstrates how to use the Cookie Store API. Our example will allow users to toggle between light and dark themes, with their preference persisting across page reloads and browser sessions.

First, let's look at the HTML structure:

<div class="container">
  <h1>CookieStore API Demo</h1>
  <button class="theme-switcher" onclick="toggleTheme()">Toggle Theme</button>
  <div class="cookie-info">
    <h3>Current Cookie State:</h3>
    <div id="cookieDisplay"></div>
  </div>
</div>
Enter fullscreen mode Exit fullscreen mode

Now, let's implement the core functionality using the CookieStore interface:

// Check if CookieStore API is supported
if ("cookieStore" in window) {
  // Listen for cookie changes
  cookieStore.addEventListener("change", (event) => {
    console.log("Cookie change detected:", event);
    updateCookieDisplay();
  });
}

// Initialize theme on page load
async function initializeTheme() {
  try {
    const themeCookie = await cookieStore.get("theme");
    if (themeCookie && themeCookie.value === "dark") {
      document.body.classList.add("dark-theme");
    }
    updateCookieDisplay();
  } catch (error) {
    console.error("Error reading theme cookie:", error);
  }
}

// Toggle theme and save preference
async function toggleTheme() {
  const isDarkTheme = document.body.classList.toggle("dark-theme");

  try {
    await cookieStore.set({
      name: "theme",
      value: isDarkTheme ? "dark" : "light",
      expires: Date.now() + 30 * 24 * 60 * 60 * 1000, // 30 days
      sameSite: "strict",
    });
  } catch (error) {
    console.error("Error saving theme preference:", error);
  }
}
Enter fullscreen mode Exit fullscreen mode

Let's break down the key features:

  1. Async/Await Pattern: The API uses promises, making it compatible with async/await syntax. This results in cleaner code compared to callback-based approaches.
  2. Cookie Change Detection: The CookieStore interface provides an event listener for listening to cookie changes. This allows us to react to cookie modifications in real-time.
  3. Simplified Reading and Writing: Notice how we can directly get and set cookies using methods like set(), get() and getAll() without string manipulation.

Here’s the complete code for you to try yourself and a demo of how it works.

Demo showing how the toggle switch works with CookieStore

Browser Support and Fallbacks

As of 2024, the CookieStore API is not universally supported across all browsers. Chrome and Edge support it, while Firefox and Safari are still working on implementation.

Image showing browser compatibility for Cookie Store API

Image from MDN

For production applications, you should implement a fallback mechanism. You should check if cookieStore is available in the Window object. Here’s an example:

class CookieManager {
  constructor() {
    this.useModernAPI = "cookieStore" in window;
  }

  async setCookie(name, value, options = {}) {
    if (this.useModernAPI) {
      return cookieStore.set({ name, value, ...options });
    }

    // Fallback to traditional approach
    let cookie = `${name}=${value}`;
    if (options.expires) {
      cookie += `; expires=${new Date(options.expires).toUTCString()}`;
    }
    if (options.path) {
      cookie += `; path=${options.path}`;
    }
    document.cookie = cookie;
  }

  async getCookie(name) {
    if (this.useModernAPI) {
      return cookieStore.get(name);
    }

    // Fallback implementation
    const value = `; ${document.cookie}`;
    const parts = value.split(`; ${name}=`);
    if (parts.length === 2) {
      return {
        name,
        value: parts.pop().split(";").shift(),
      };
    }
    return null;
  }
}
Enter fullscreen mode Exit fullscreen mode

This example defines a class with two methods getCookie() and setCookie(). These methods use the CookieStore methods if available; otherwise, they fall back to document.cookie.

Wrap-up

The Cookie Store API significantly improves cookie handling. Its promise-based interface, built-in change detection and cleaner methods make it a powerful tool for modern web development. While browser support is still growing, implementing it with appropriate fallbacks allows you to write durable code while being future-ready. Check the MDN documentation for more information about the Cookie Store API.

Originally published on Telerik.

Heroku

Built for developers, by developers.

Whether you're building a simple prototype or a business-critical product, Heroku's fully-managed platform gives you the simplest path to delivering apps quickly — using the tools and languages you already love!

Learn More

Top comments (4)

Collapse
 
nathan_tarbert profile image
Nathan Tarbert

Man, I remember fighting with document.cookie and this is a huge upgrade. Love seeing things finally get easier like this.

Collapse
 
nadeem_zia_257af7e986ffc6 profile image
nadeem zia

Good explanation given about Cookies, good work

Collapse
 
javascriptwizzard profile image
Pradeep

Very useful! A very neat replacement for document.cookie. Thanks for sharing!

Collapse
 
pmbanugo profile image
Peter Mbanugo

I'm glad you liked it

Some comments may only be visible to logged-in visitors. Sign in to view all comments.

DevCycle image

Ship Faster, Stay Flexible.

DevCycle is the first feature flag platform with OpenFeature built-in to every open source SDK, designed to help developers ship faster while avoiding vendor-lock in.

Start shipping