How document.cookie Parses and Writes Cookies

The document.cookie property in browser JavaScript provides an interface to read and write HTTP cookies associated with the current document. Rather than acting as a standard string variable, document.cookie functions as a getter and setter with distinct behavioral rules for parsing and assignment. This article explains how the browser handles writes through this property, how it exposes existing cookies for reading, and how to effectively parse and serialize cookie strings.

How Writing Cookies Works (The Setter)

When you assign a string to document.cookie, you do not overwrite the entire cookie store. Instead, the browser’s setter intercepts the assignment, parses the string as a single cookie definition, and updates the browser’s internal cookie jar.

document.cookie = "username=JohnDoe; max-age=3600; path=/; Secure; SameSite=Lax";

The Structure of a Write String

A write string consists of a primary name=value pair followed by optional semicolon-separated control attributes (directives):

Behavior and Limitations of the Setter

  1. One at a Time: You cannot set multiple cookies in a single assignment. Setting document.cookie = "a=1; b=2" sets the cookie named a with the value 1 and treats b=2 as an invalid directive, ignoring it.
  2. Deletion: To delete a cookie, set its max-age to 0 (or its expiration date to the past) using the exact matching name, path, and domain attributes.
  3. No HttpOnly Access: JavaScript cannot set the HttpOnly flag; this directive can only be set by the server via the Set-Cookie HTTP response header.

How Reading Cookies Works (The Getter)

Accessing document.cookie invokes an internal getter that queries the browser’s cookie storage, filters the accessible cookies, and concatenates them into a single string.

console.log(document.cookie);
// Output: "theme=dark; username=JohnDoe; session_id=abc123"

Key Rules of the Getter Output


Parsing document.cookie into a JavaScript Object

Because the getter returns a flat string, client-side code must parse it to access specific values. A standard parsing approach splits the string and decodes the components:

function getCookies() {
  const cookies = {};
  if (!document.cookie) return cookies;

  document.cookie.split("; ").forEach(cookie => {
    const [name, ...valueParts] = cookie.split("=");
    const value = valueParts.join("=");
    cookies[decodeURIComponent(name)] = decodeURIComponent(value);
  });

  return cookies;
}

// Example usage:
const allCookies = getCookies();
console.log(allCookies.username); // "JohnDoe"

Modern browsers support the asynchronous cookieStore API, which replaces the manual string parsing and serialization required by document.cookie:

// Reading a cookie
async function readTheme() {
  const cookie = await cookieStore.get("theme");
  console.log(cookie?.value);
}

// Writing a cookie
async function setTheme() {
  await cookieStore.set({
    name: "theme",
    value: "dark",
    path: "/",
    sameSite: "lax"
  });
}

The Cookie Store API provides standard JavaScript objects, supports service workers, and avoids synchronous blocking of the main thread.