Complete JavaScript Course Module 10: Intermediate: The Browser Object Model (BOM)

JavaScript Cookies: Create, Read and Delete Cookies

  • Beginner
  • Lesson 10.6
  • 7 min read
  • 46 of 76 in the course

In short

JavaScript cookies are small pieces of text a website stores in the browser and sends to the server with every request. Learn how to create, read and delete cookies with document.cookie, set expiry, path and SameSite, and when to use localStorage instead. What are cookies?

JavaScript cookies are small pieces of text a website stores in the browser and sends to the server with every request. Learn how to create, read and delete cookies with document.cookie, set expiry, path and SameSite, and when to use localStorage instead.

What are cookies?

A cookie is a small piece of text (up to about 4 KB) that a website saves in your browser, as a name=value pair. The special thing about cookies is that the browser sends them back to the server automatically with every request to that site. That is how a website "remembers" you are logged in when you move from page to page.

A real-life comparison: a cookie is like the cloakroom ticket you get at a theatre. You show it every time you come back, and the staff know which coat is yours.

Cookies are used for:

  • Sessions: keeping you logged in, remembering your shopping cart.
  • Preferences: language, theme, "don't show this banner again".
  • Tracking: analytics and advertising (this is where privacy rules apply).

In JavaScript, cookies live in document.cookie. It is a strange property: when you assign to it, you add or update one cookie, not replace them all.

document.cookie = "theme=dark";
document.cookie = "language=en";

console.log(document.cookie);
// Output: theme=dark; language=en

Even though we assigned twice, both cookies are kept. Reading document.cookie gives one string with all cookies for this page, separated by "; ". Without any extra settings, these are session cookies: they disappear when the browser is closed.

Cookie values must not contain ;, , or spaces safely, so wrap any user text with encodeURIComponent():

const city = "São Paulo; Brazil";
document.cookie = `city=${encodeURIComponent(city)}`;
console.log(document.cookie);
// Output: theme=dark; language=en; city=S%C3%A3o%20Paulo%3B%20Brazil

Note: Run these examples on a real web page served over http:// or https:// (for example http://localhost). Cookies are not saved on pages opened directly from a file (file://) in most browsers.

After the name=value part you can add attributes, separated by ;. They tell the browser how long to keep the cookie and when to send it.

AttributeExampleWhat it does
max-agemax-age=86400Keep for this many seconds (86400 = 1 day)
expiresexpires=Fri, 31 Dec 2027 23:59:59 GMTKeep until this date (UTC string)
pathpath=/Which pages can see the cookie; / means the whole site
domaindomain=example.comShare with subdomains like shop.example.com
SameSiteSameSite=LaxWhether the cookie is sent from other sites (Strict, Lax, None)
SecureSecureOnly send over HTTPS
HttpOnly(server only)JavaScript cannot read the cookie at all
// Remember the theme for 30 days on the whole site
const thirtyDays = 60 * 60 * 24 * 30;
document.cookie = `theme=dark; max-age=${thirtyDays}; path=/; SameSite=Lax; Secure`;

// The same with expires and a Date
const expiryDate = new Date(Date.now() + thirtyDays * 1000);
document.cookie = `theme=dark; expires=${expiryDate.toUTCString()}; path=/; SameSite=Lax; Secure`;

console.log(document.cookie);
// Output (example): theme=dark

Reading document.cookie only ever shows name=value pairs. The attributes are stored by the browser but never returned to JavaScript. max-age is simpler than expires because you do not need a date; if both are given, max-age wins.

A few rules worth knowing:

  • SameSite=Lax is the default in modern browsers: the cookie is sent when the user clicks a link to your site, but not with hidden requests from other sites. This protects against an attack called CSRF. SameSite=None must always come with Secure.
  • Secure cookies are only saved and sent on HTTPS pages (browsers treat localhost as secure too).
  • HttpOnly can only be set by the server with a Set-Cookie header. JavaScript cannot create, read or delete such cookies. This is exactly why login cookies should be HttpOnly: even if an attacker injects a script, they cannot steal the session.

Common mistake: Setting a cookie with path=/ and trying to delete it without path=/. A cookie is identified by its name plus its path and domain. To update or delete it, you must use the same path and domain as when you created it.

Helper functions to set, get and delete cookies

Working with that one long string is clumsy, so most projects use three small helper functions:

function setCookie(name, value, days = 7) {
  const maxAge = days * 24 * 60 * 60;
  document.cookie =
    `${encodeURIComponent(name)}=${encodeURIComponent(value)}; ` +
    `max-age=${maxAge}; path=/; SameSite=Lax`;
}

function getCookie(name) {
  const cookies = document.cookie ? document.cookie.split("; ") : [];
  for (const cookie of cookies) {
    const [key, ...rest] = cookie.split("=");
    if (decodeURIComponent(key) === name) {
      return decodeURIComponent(rest.join("="));
    }
  }
  return null; // not found
}

function deleteCookie(name) {
  // A max-age of 0 tells the browser to remove it now
  document.cookie = `${encodeURIComponent(name)}=; max-age=0; path=/; SameSite=Lax`;
}

setCookie("username", "Maya Lopez", 30);
console.log(getCookie("username"));   // Output: Maya Lopez
console.log(getCookie("nothing"));    // Output: null

deleteCookie("username");
console.log(getCookie("username"));   // Output: null

setCookie encodes the name and value and saves the cookie for a number of days. getCookie splits the string into "name=value" pieces, splits each piece at the first = (the ...rest part keeps any = signs inside the value), and returns the matching value or null. deleteCookie overwrites the cookie with an empty value and max-age=0, which tells the browser to throw it away. You can check the results in DevTools under Application (Chrome, Edge) or Storage (Firefox), in the Cookies section.

Here is a practical use, a "dismiss banner" that stays hidden for 90 days:

<!DOCTYPE html>
<html lang="en">
<body>
  <div id="banner" style="background: #fff3cd; padding: 12px;">
    New: free delivery on orders over €30!
    <button id="closeBanner">Close</button>
  </div>

  <script>
    const getCookie = (name) =>
      document.cookie.split("; ").find((c) => c.startsWith(name + "="))?.split("=")[1] ?? null;

    const banner = document.querySelector("#banner");

    if (getCookie("bannerClosed") === "yes") {
      banner.hidden = true;
    }

    document.querySelector("#closeBanner").addEventListener("click", () => {
      banner.hidden = true;
      document.cookie = `bannerClosed=yes; max-age=${60 * 60 * 24 * 90}; path=/; SameSite=Lax`;
    });
  </script>
</body>
</html>

Open the page (on http://localhost), close the banner and reload: it stays hidden. Delete the cookie in DevTools and reload: it comes back. The short getCookie arrow function uses optional chaining ?. so it returns null safely when the cookie is missing.

Cookies vs localStorage: which should you use?

You learned about localStorage in the Saving Data lesson. Both store small strings in the browser, but they solve different problems:

CookieslocalStorage
Size limitAbout 4 KB per cookieAbout 5 MB per site
Sent to the server?Yes, with every requestNo, stays in the browser
ExpiryYou choose (max-age / expires) or end of sessionNever, until deleted
Readable by JavaScript?Yes, unless HttpOnlyAlways
APIOne awkward string (document.cookie)Simple methods (setItem, getItem)
Best forLogins and data the server needsPreferences and data only your page needs

A simple rule: if the server needs the value on every request (like a session ID), use a cookie, ideally an HttpOnly one set by the server. If only your JavaScript needs it (like a theme or a draft), use localStorage: it is bigger, easier and does not slow down every request.

Cookies can be used to follow people across websites, so many laws regulate them. In the European Union and the UK, for example, rules like the GDPR and ePrivacy laws say you must ask for consent before setting cookies that are not strictly necessary, such as analytics or advertising cookies. Cookies that the site truly needs to work, like a login session or a shopping cart, usually do not need consent. Similar laws exist in other places too.

Tip: Store as little as possible, never put passwords or personal details in a cookie, and do not load analytics or ad scripts until the user has said yes. If you are building a real business site, check the rules that apply in your country.

Practice exercise

Build a "visit counter" that uses cookies. When the page loads, read a cookie named visits with your getCookie helper, turn it into a number (default 0), add 1, save it back for 365 days with setCookie, and show "You have visited this page 5 times". Add a "Reset" button that calls deleteCookie("visits") and updates the text.

Hint: use Number(getCookie("visits") ?? 0) + 1, and remember to serve the page from http://localhost so the cookie is saved.

Key takeaways

  • Cookies are small name=value strings that the browser sends to the server with every request.
  • Assigning to document.cookie adds or updates one cookie; reading it returns all of them as one string.
  • Use max-age or expires for lifetime, path=/ for the whole site, SameSite=Lax and Secure for safety; HttpOnly can only be set by the server.
  • Delete a cookie by setting max-age=0 with the same name, path and domain.
  • Use cookies for data the server needs, localStorage for data only your page needs, and ask for consent before non-essential cookies.