JavaScript Developer Guide to Browser Cookies

Master cookie creation, security attributes, and modern best practices for building secure web applications

What Are Browser Cookies?

Browser cookies remain a fundamental technology for web applications, enabling session management, personalization, and state preservation across the stateless HTTP protocol. Despite their widespread use and the emergence of alternative storage APIs, cookies continue to be essential for authentication flows, shopping carts, and cross-site request protection.

Our web development services team implements secure cookie handling as part of robust authentication and session management systems.

The Cookie Lifecycle

The cookie lifecycle begins when a server includes one or more Set-Cookie headers in its HTTP response. When the browser receives this response, it stores the specified cookie data. On subsequent requests to the same domain, the browser automatically includes all applicable cookies in the Cookie header, allowing the server to recognize the user or maintain application state.

Cookie Size and Quantity Limits

Modern browsers typically impose limits on cookie storage, including a maximum number of cookies per domain (usually around 150-300 cookies) and a maximum size per cookie (typically 4KB). These constraints make cookies unsuitable for storing large amounts of data, which is why developers should consider alternatives like localStorage or IndexedDB for client-side caching needs.

Creating and Managing Cookies with JavaScript
1// Creating a simple session cookie2document.cookie = "userId=abc123";3 4// Creating a cookie with expiration (7 days from now)5const expirationDate = new Date();6expirationDate.setDate(expirationDate.getDate() + 7);7document.cookie = `sessionToken=xyz789; expires=${expirationDate.toUTCString()}`;8 9// Creating a secure cookie with SameSite policy10document.cookie = "preferences=dark-mode; path=/; secure; SameSite=Lax";11 12// Delete a cookie by setting expiration to the past13document.cookie = "userId=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/";

The Cookie Store API

For modern browsers, the Cookie Store API provides a promise-based alternative to the traditional document.cookie approach. This API offers better performance because it doesn't require serializing and parsing cookie strings, and it integrates naturally with async/await patterns common in modern JavaScript applications.

// Using the Cookie Store API (modern browsers only)
async function manageCookies() {
 // Set a cookie
 await cookieStore.set('userId', 'abc123', {
 expires: new Date('2027-01-01'),
 path: '/',
 sameSite: 'lax'
 });

 // Get a specific cookie
 const userCookie = await cookieStore.get('userId');
 console.log(userCookie.value);

 // Delete a cookie
 await cookieStore.delete('userId');
}

Cookie Attributes Deep Dive

Expires and Max-Age

The Expires attribute specifies an exact date and time when the cookie should be deleted, formatted as a UTC string (e.g., "Thu, 31 Dec 2026 23:59:59 GMT"). The Max-Age attribute specifies the cookie's lifetime in seconds from the moment it's set. When both are-Agetakes present,Max precedence.

Domain

The Domain attribute controls which domains can receive the cookie. If not specified, the cookie is restricted to the exact domain that set it. When a domain is specified, the cookie is sent to that domain and all its subdomains, which is useful for applications that need to share authentication state across services.

Path

The Path attribute restricts cookie transmission to requests for URLs beginning with the specified path. Setting path=/ makes the cookie available across the entire domain, while more specific paths limit the cookie's scope.

Secure

The Secure attribute instructs the browser to only send the cookie over HTTPS connections. This prevents cookies from being transmitted over unencrypted connections where they could be intercepted by attackers.

HttpOnly

The HttpOnly attribute prevents JavaScript access to the cookie through document.cookie and the Cookie Store API. This provides protection against cross-site scripting (XSS) attacks that might attempt to steal cookie values. Authentication tokens and session identifiers should always use HttpOnly cookies.

SameSite Attribute

The SameSite attribute controls when cookies are sent with cross-site requests, providing crucial protection against cross-site request forgery (CSRF) attacks.

SameSite Values Explained

SameSite=Strict -- The cookie is only sent in first-party contexts. This provides the strongest CSRF protection but can break legitimate cross-site flows.

SameSite=Lax -- The cookie is sent with top-level navigations and within same-site subresource requests. This balances security with usability.

SameSite=None -- The cookie is sent with all requests, including cross-party ones. This requires the Secure attribute and should only be used when cross-site cookie transmission is genuinely needed.

Set-Cookie: session=abc123; SameSite=Strict; Secure
Set-Cookie: preference=dark; SameSite=Lax; Secure
Set-Cookie: tracking=xyz789; SameSite=None; Secure
SameSite Cookie Comparison

Strict

Cookie sent only for same-site navigations. Maximum CSRF protection.

Lax

Sent for top-level navigations and same-site requests. Balances security and usability.

None

Sent for all requests. Requires Secure attribute. Use only when necessary.

Partitioned Cookies (CHIPS)

Cookies Having Independent Partitioned State (CHIPS) is a new specification that allows third-party cookies to work in a privacy-preserving way. When a cookie is marked as Partitioned, browsers isolate it by top-level site, preventing cross-site tracking while still enabling legitimate third-party functionality.

Set-Cookie: embedConfig=settings; Partitioned; SameSite=None; Secure

This cookie would be isolated per top-level site, meaning an embedded widget on different sites would receive different cookie values, preventing the third-party service from tracking users across sites.

First-Party vs. Third-Party Cookies

First-party cookies are set by the domain the user is currently visiting. These cookies support core functionality like session management, language preferences, and shopping carts. Third-party cookies are set by domains other than the one displayed in the browser address bar, typically for advertising, analytics, or cross-site tracking purposes.

The distinction matters because browsers are increasingly restricting third-party cookies to protect user privacy. Safari blocks third-party cookies by default, Firefox has Enhanced Tracking Protection, and Chrome is developing mechanisms to phase out third-party cookies entirely.

Detecting Third-Party Cookie Blocking

Detecting whether third-party cookies are blocked requires testing in an actual third-party context, typically through an iframe. The navigator.cookieEnabled property only indicates whether first-party cookies work, not whether third-party cookies are blocked.

Security Best Practices

Authentication Cookie Guidelines

Authentication cookies require the highest level of security attention. They should always include the HttpOnly and Secure attributes, use appropriate SameSite settings (typically Strict or Lax), and have reasonable expiration times.

For professional implementation of secure authentication systems, our web development services team follows industry best practices for cookie security and session management.

Cookie Prefix Conventions

Cookie name prefixes provide additional security guarantees:

  • __Host- prefix: Cookies must have the Secure attribute, cannot have a Domain attribute, must have Path=/, and are only sent to the host that set them.
  • __Secure- prefix: Cookies must have the Secure attribute and are only accepted from HTTPS origins.
Set-Cookie: __Host-session=abc123; Secure; Path=/; HttpOnly; SameSite=Strict
Set-Cookie: __Secure-csrf-token=xyz789; Secure; Path=/; SameSite=Strict

Common Pitfalls and How to Avoid Them

Cookie Attribute Mismatches

One of the most common cookie-related bugs occurs when attempting to update or delete a cookie with different attributes than those used when it was originally set. This creates duplicate cookies rather than modifying the existing one.

Path and Domain Confusion

The Domain determines which hosts receive the cookie, while Path determines which URL paths trigger cookie transmission. A cookie set with Domain=example.com and Path=/api is sent to all subdomains but only for URLs starting with /api.

Case Sensitivity

Cookie names are case-sensitive. A cookie named "UserID" is different from "userID" or "USERID". This can lead to bugs when code assumes cookie names are case-insensitive.

Encoding and Special Characters

Cookie values should be properly URL-encoded to handle special characters, spaces, and Unicode content. Strict encoding ensures compatibility across all browsers.

Modern Alternatives to Cookies

Web Storage API

localStorage and sessionStorage provide simpler key-value storage with 5-10MB capacity. Not sent with HTTP requests.

IndexedDB

Transactional, object-oriented database for complex data structures and large amounts of client-side data.

Service Workers

Enable sophisticated caching strategies for offline functionality and network request control.

Testing and Debugging Cookies

Browser DevTools

All modern browsers provide cookie inspection and management in their developer tools. Chrome DevTools shows cookies under the Application tab, allowing you to view, edit, and delete cookies, as well as observe cookie transmission in the Network panel.

Automated Testing with Playwright

// Example with Playwright
test('authentication cookie is set on login', async ({ page }) => {
 await page.goto('/login');
 await page.fill('[name="email"]', '[email protected]');
 await page.fill('[name="password"]', 'password123');
 await page.click('button[type="submit"]');

 // Verify cookie was set
 const cookies = await page.context().cookies();
 const sessionCookie = cookies.find(c => c.name === 'sessionToken');
 expect(sessionCookie).toBeDefined();
 expect(sessionCookie.httpOnly).toBe(true);
 expect(sessionCookie.secure).toBe(true);
});

Conclusion

Browser cookies remain an essential tool for web developers, despite the emergence of alternative storage technologies. Understanding cookie attributes, security best practices, and the evolving browser landscape is crucial for building secure, user-friendly web applications.

Our web development services team specializes in implementing secure, standards-compliant cookie handling and authentication systems.

Key Takeaways

  • Always use Secure and HttpOnly attributes for sensitive cookies
  • Choose appropriate SameSite values based on your cross-site requirements
  • Test cookie functionality across different browsers and privacy settings
  • Consider alternative storage options for client-side data that doesn't need server transmission
  • Implement graceful degradation for users with restricted cookie settings

As browsers continue to enhance privacy protections, developers should design applications that gracefully handle cookie restrictions while planning for a future where third-party cookies may no longer be available.

Frequently Asked Questions

What is the difference between session cookies and persistent cookies?

Session cookies are deleted when the browser session ends, while persistent cookies have an expiration date and remain on the user's device until that date passes. Session cookies don't include Expires or Max-Age attributes, while persistent cookies specify when they should be deleted.

Can JavaScript create HttpOnly cookies?

No, HttpOnly cookies can only be set by the server through the Set-Cookie header. This is by design for security purposes--HttpOnly protects against XSS attacks by preventing JavaScript from accessing the cookie.

How do I delete a cookie with JavaScript?

To delete a cookie, set its expiration to a date in the past or set max-age to 0, using the exact same name, domain, and path attributes that were used when creating the cookie. For example: document.cookie = 'name=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/';

What is the difference between localStorage and cookies?

localStorage stores data that isn't sent to the server with each request (up to 5-10MB per origin), while cookies are sent with every HTTP request. localStorage data persists until explicitly deleted, while cookies can have expiration dates. localStorage is better for client-side caching; cookies are better for data that the server needs to receive.

How do SameSite cookies prevent CSRF attacks?

SameSite cookies restrict when cookies are sent with cross-site requests. With SameSite=Strict, cookies are never sent on cross-site requests. With SameSite=Lax, they're only sent on top-level navigations. This prevents attackers from tricking browsers into making authenticated requests to your site from malicious pages.

Need Help Building Secure Web Applications?

Our team of JavaScript experts can help you implement secure cookie handling, authentication systems, and modern web application architecture.