A cookie is a small name-value record associated with an origin and request scope. Use cookies for deliberately scoped browser-server state, not as a general store for sensitive application data.
| Cookie field | Effect |
|---|---|
| name=value | Stores the cookie value under a name. Encode values that contain unsupported characters. |
| Expires / Max-Age | Sets a persistent lifetime. Without either field, the cookie is normally session-scoped. |
| Domain | Controls which matching hosts may receive the cookie; omit it for a host-only cookie. |
| Path | Limits the request paths that receive the cookie; it is not a security boundary. |
| Secure | Sends the cookie only over secure transport, except defined localhost behavior. |
| HttpOnly | Prevents JavaScript access; set this on the server for session cookies that scripts do not need. |
| SameSite | Controls cross-site sending behavior and participates in CSRF defense. |
A cookie can be easily created using document.cookie in JavaScript like below-
document.cookie = "Cookie_name = Cookie_value; expires = Wed, 21 Aug 2019 21:00:00 UTC; path = /"
A cookie can be easily updated using document.cookie in JavaScript like below-
The old cookie will be overwritten bye new cookie.
document.cookie = "Cookie_name = Cookie_value; expires = Wed, 27 Nov 2019 23:00:00 UTC; path = /"
A cookie can be easily retrieved using document.cookie in JavaScript like below-
In JavaScript document.cookie will return all the available cookies in one string, like- cookie1 = value; cookie2 = value; cookie3 = value;
const cookies = document.cookie;
To delete a cookie, just set the value of the cookie to empty and expires parameter to a passed date.
document.cookie = "Cookie_name = ; expires = Thu, 01 Jan 1970 00:00:00 UTC; path = /"
Working with document.cookie directly can be cumbersome. Here are reusable helper functions for setting, getting, and deleting cookies.
// Set a cookie with optional expiry days
function setCookie(name, value, days = 7) {
const expires = new Date();
expires.setTime(expires.getTime() + days * 24 * 60 * 60 * 1000);
document.cookie = `${encodeURIComponent(name)}=${encodeURIComponent(value)};expires=${expires.toUTCString()};path=/;SameSite=Lax`;
}
// Get a cookie by name
function getCookie(name) {
const key = encodeURIComponent(name) + '=';
const cookies = document.cookie.split(';');
for (let cookie of cookies) {
cookie = cookie.trim();
if (cookie.startsWith(key)) {
return decodeURIComponent(cookie.substring(key.length));
}
}
return null;
}
// Delete a cookie
function deleteCookie(name) {
document.cookie = `${encodeURIComponent(name)}=;expires=Thu, 01 Jan 1970 00:00:00 UTC;path=/`;
}
// Usage
setCookie('username', 'Alice', 30);
console.log(getCookie('username')); // Alice
deleteCookie('username');
console.log(getCookie('username')); // null
| Feature | Cookies | localStorage | sessionStorage |
|---|---|---|---|
| Capacity | ~4KB | ~5-10MB | ~5-10MB |
| Sent to server | Yes (every request) | No | No |
| Expiry | Configurable | Never (manual) | Tab close |
| Accessible from | JS + Server | JS only | JS only |
| Use case | Auth tokens, tracking | User preferences | Temp session data |
A cookie is a small name-value record stored by the user agent and selected for HTTP requests according to attributes such as domain, path, expiration, security, and same-site context. The server creates cookies with `Set-Cookie`; eligible cookies return in the `Cookie` request header. They are not general client storage because they add bytes to matching requests and participate in authentication and privacy boundaries.
Host-only cookies omit `Domain` and return only to the host that set them. A Domain cookie can include eligible subdomains and therefore has a wider trust surface. `Path` controls when the browser sends the cookie but is not a strong isolation boundary between applications on the same host. Use the narrowest host and path that satisfy the protocol.
A session cookie has no persistent expiration attribute, while `Max-Age` or `Expires` makes it persistent. `Max-Age` takes precedence when both are present. Browser session restoration can affect intuitive “close the browser” expectations, so the server must enforce inactivity and absolute session expiry independently of client storage duration.
Cookie names and values have encoding restrictions. Encode application values deliberately and keep them small. Do not place full user profiles, authorization decisions, or sensitive plaintext in a cookie. Even a signed value can be read unless separately protected, and an encrypted value still needs expiry, replay, rotation, and size controls.
`document.cookie` returns one semicolon-separated string containing cookies visible to the current document; HttpOnly cookies are intentionally absent. Assigning to it sets one cookie rather than replacing the entire collection. Parsing must split pairs carefully, trim optional whitespace, and decode only the encoding the application used.
JavaScript cannot create an HttpOnly cookie because that attribute exists to prevent script access. Authentication session cookies should normally be issued by the server with appropriate attributes. The asynchronous Cookie Store API can avoid synchronous document-cookie access in supported contexts, but compatibility and service-worker requirements must be evaluated before relying on it.
Delete a cookie by setting an expiration in the past or `Max-Age=0` with the same name, domain, and path scope used when it was created. A deletion at `/` does not remove a same-named cookie scoped to another path or domain. Inventory duplicate names because request ordering and server parsing can become ambiguous.
Wrap non-sensitive script-readable preferences in a small tested helper that owns encoding, scope, defaults, and deletion. Do not create a generic helper that silently applies insecure defaults to authentication data. Handle cookies being blocked, cleared, expired, or limited by browser privacy settings as normal runtime conditions.
`Secure` limits cookie transmission to secure contexts, while `HttpOnly` prevents JavaScript APIs from reading the value. `SameSite=Strict`, `Lax`, or `None` controls cross-site request inclusion according to browser rules; `None` requires `Secure`. Select the least cross-site behavior compatible with login redirects, embedded content, and external integrations.
SameSite is defense in depth for cross-site request forgery, not a complete authorization model. State-changing endpoints still need safe methods, origin or token defenses as appropriate, and server-side permission checks. HttpOnly reduces session theft through script but injected script can still issue same-origin actions as the user, so prevent XSS as well.
The `__Secure-` and `__Host-` prefixes impose attribute requirements in supporting browsers. A `__Host-` cookie requires Secure, Path `/`, and no Domain, reducing overwrite and scope risk. Newer Http-prefixed variants can signal header-set HttpOnly cookies where supported. Prefixes supplement, not replace, server validation and compatibility testing.
Regenerate session identifiers after authentication and privilege changes, reject identifiers the server did not issue, invalidate sessions on logout and risk events, and avoid accepting session IDs in URLs. Session IDs need high entropy and should carry no meaningful account data. Use the framework’s maintained session implementation rather than inventing token generation and revocation.
A cookie is first-party when its site context matches the top-level site and third-party when used in a different site context. Browser policy increasingly restricts third-party storage, so embedded integrations must not assume historical behavior. Test blocked-cookie paths and use explicit top-level or standardized access flows rather than fingerprinting workarounds.
Partitioned cookies use an additional top-level-site key in supporting browsers, reducing cross-site correlation while allowing some embedded state. They require Secure and have specific compatibility constraints. Partitioning changes where a cookie is available; it does not make the value safe, remove consent duties, or replace authentication and CSRF controls.
Classify each cookie as strictly necessary, preference, analytics, advertising, or another legally reviewed purpose. Set non-essential cookies only after the required consent in applicable jurisdictions, record the choice, provide withdrawal, and avoid loading third-party code before consent merely because the application plans to delete its cookies later.
Test attributes in browser developer tools and actual request headers over HTTPS. Cover subdomains, paths, same-site and cross-site navigation, iframe contexts, expiry, clock differences, logout, session rotation, blocked storage, duplicate names, and consent withdrawal. Automated server tests should assert every `Set-Cookie` attribute instead of depending on a manual checklist.
Use a cookie when the browser must attach a small value to matching HTTP requests, especially an opaque server session identifier. Use `sessionStorage` for non-sensitive tab-scoped client state and `localStorage` for non-sensitive origin-scoped preferences that may persist, while accounting for synchronous access and cross-tab behavior. Use IndexedDB for larger structured offline data.
Do not store authentication or refresh credentials in script-readable Web Storage merely to avoid cookie attributes. Any script running in the origin can read those values after an XSS compromise. A server-managed HttpOnly cookie protects confidentiality from script access, although the application still needs XSS and CSRF defenses because malicious script can trigger requests.
Keep authoritative account, cart, permission, and workflow state on the server when it must survive device changes, support concurrency, or resist tampering. A client cookie can hold a signed reference or preference, but the server should validate every value and load the current record. Choose storage from request transport, sensitivity, scope, capacity, lifetime, offline need, and synchronization rather than convenience.
Explore 500+ free tutorials across 20+ languages and frameworks.