Question

Set and Read Cookies in JavaScript for CSS Theme Selection

htmljavascriptcsscookies

Question

How can I save the CSS file selected in a <select> element to a JavaScript cookie for approximately one week, then read that cookie when the page is opened again and restore the previously selected stylesheet?

The page contains options such as:

<select id="myList">
  <option value="style-1.css">CSS1</option>
  <option value="style-2.css">CSS2</option>
  <option value="style-3.css">CSS3</option>
  <option value="style-4.css">CSS4</option>
</select>

How should the cookie value, expiration date, and stylesheet update be written correctly in JavaScript?

Short Answer

You will learn how browser cookies store small name/value settings, how to write and read them safely in JavaScript, and how to use a saved value to restore a visitor's CSS theme. You will also see when localStorage is a simpler choice for this kind of preference.

Concept

A cookie is a small piece of text stored by the browser for a website. It consists of a name and a value, plus optional attributes that control where and how long it is available.

A typical cookie assignment looks like this:

document.cookie = "theme=style-2.css; max-age=604800; path=/";

This creates a cookie named theme with the value style-2.css:

  • max-age=604800 keeps it for 604,800 seconds, which is seven days.
  • path=/ makes it available on every page under the site's root path.

Reading cookies is different from assigning one. document.cookie returns one string containing all cookies available to the current page, for example:

theme=style-2.css; language=en

Your code must find the cookie with the name it needs.

For a theme selector, the usual flow is:

  1. The visitor selects a stylesheet.
  2. JavaScript changes the <link> element's href.
  3. JavaScript saves the selected filename in a cookie.
  4. On a later visit, JavaScript reads the cookie and reapplies that filename.

Cookies are useful when a server might also need access to the preference. For a preference used only by client-side JavaScript, localStorage is often easier because it has a direct key/value API.

Mental Model

Think of cookies as small labeled notes kept by the browser for a particular website.

  • The label is the cookie name, such as theme.
  • The note's content is the value, such as style-3.css.
  • The expiry date tells the browser when to throw the note away.
  • The path tells the browser which parts of the website can see it.

When the visitor returns, your code asks: “Do I have a note labeled theme?” If it does, it uses the value on that note to load the same stylesheet.

Take Quiz

Syntax and Examples

Use a helper function to write cookies and another one to locate a cookie by name.

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

function getCookie(name) {
  const target = `${encodeURIComponent(name)}=`;
  const cookies = document.cookie.split(";");

  for (const cookie of cookies) {
    const trimmedCookie = cookie.trim();

    if (trimmedCookie.startsWith(target)) {
      return decodeURIComponent(trimmedCookie.slice(target.length));
    }
  }

  return null;
}

Use those helpers with a stylesheet <link> and a <select>.

<link id="css" rel="stylesheet" href="style-1.css">

<select id="myList">
  <option value="style-1.css">CSS1</option>
  <option value="style-2.css">CSS2</option>
  <option value="style-3.css">CSS3</option>
  <option value="style-4.css">CSS4</option>
</select>
const stylesheet = document.getElementById("css");
const selector = document.getElementById("myList");

selector.addEventListener("change", function () {
  stylesheet.href = this.value;
  setCookie("theme", this.value, 7);
});

this.value is the selected option's value inside a regular event-handler function. The filename is both applied immediately and stored for seven days.

encodeURIComponent and decodeURIComponent allow values containing spaces or special characters to be stored and recovered safely.

Step by Step Execution

Consider this code run after the page's HTML has loaded:

const savedTheme = getCookie("theme");

if (savedTheme) {
  document.getElementById("css").href = savedTheme;
  document.getElementById("myList").value = savedTheme;
}

Suppose the browser currently has this cookie:

theme=style-3.css

The execution is:

  1. getCookie("theme") reads the full document.cookie string.
  2. It splits the string into individual cookie entries.
  3. It finds the entry beginning with theme=.
  4. It returns style-3.css and assigns it to savedTheme.
  5. The if (savedTheme) condition is true because the string is not empty.
  6. The <link id="css"> element gets href="style-3.css", so the browser loads that stylesheet.
  7. The <select> value is changed to style-3.css, so the displayed option matches the active stylesheet.

If no theme cookie exists, getCookie returns null, the if block is skipped, and the default stylesheet remains active.

Real World Use Cases

Cookies can store small settings that should survive page reloads and later visits, including:

  • A light, dark, or high-contrast theme choice.
  • The visitor's language preference.
  • Whether a cookie notice has been dismissed.
  • A recently selected layout, dashboard view, or sort preference.
  • A server-readable preference that should be sent with later HTTP requests.

Do not use ordinary JavaScript-readable cookies to store passwords, access tokens, payment details, or other sensitive data. Cookies can be exposed to JavaScript unless they are created with the HttpOnly attribute, and JavaScript cannot set HttpOnly itself.

Take Quiz

Real Codebase Usage

In real projects, developers usually avoid scattering raw document.cookie assignments across event handlers. Instead, they put cookie parsing and writing in small reusable helpers or use a trusted library.

A theme implementation also commonly validates saved data before applying it. Cookie values can be old, manually changed, or no longer supported after a deployment.

const allowedThemes = new Set([
  "style-1.css",
  "style-2.css",
  "style-3.css",
  "style-4.css"
]);

function applyTheme(theme) {
  if (!allowedThemes.has(theme)) {
    return false;
  }

  document.getElementById("css").href = theme;
  document.getElementById("myList").value = theme;
  return true;
}

const savedTheme = getCookie("theme");

if (savedTheme) {
  applyTheme(savedTheme);
}

This is a guard clause pattern: invalid values return early instead of being used.

For a server-rendered application, a server may read the theme cookie before sending HTML. That can apply the correct theme on the first render and reduce a visible flash of the default theme. For a purely front-end preference, many codebases choose localStorage instead.

Common Mistakes

Putting JavaScript text inside the cookie value

This stores the literal text document.getElementById(...), not the element's actual href value:

// Broken: quotes make this text, not an evaluated expression.
document.cookie = "Css=document.getElementById('css').href";

Read the value first, then build the cookie string:

const href = document.getElementById("css").getAttribute("href");
document.cookie = `theme=${encodeURIComponent(href)}; max-age=604800; path=/`;

Missing cookie separators and attributes

Cookie parts must be separated by semicolons. An expiration date is not simply appended to the value.

// Broken: the browser treats the date as part of the value.
document.cookie = "theme=style-2.css" + new Date();

Use an attribute:

document.cookie = "theme=style-2.css; max-age=604800; path=/";

Using a past expiration date

A cookie expiration date in the past deletes the cookie. A hard-coded old date will not preserve a current setting.

// This date is already in the past.
new Date("February 10, 2013")

Prefer max-age for a duration such as seven days.

Treating document.cookie as one value

document.cookie can contain multiple cookies. Do not assume its entire value is your theme.

// Unreliable when more than one cookie exists.
const theme = document.cookie;

Parse by name with a getCookie helper.

Forgetting path=/

Without path=/, a cookie may only be accessible on the directory where it was created. Set an explicit path if multiple pages should use the preference.

Applying an untrusted saved stylesheet

Do not directly load arbitrary filenames from a cookie. Keep an allowlist of valid themes before setting href.

Comparisons

OptionBest forPersists after browser restart?Sent to the server automatically?
CookieSmall preferences a server may needYes, if it has an expiry or max-ageYes, when its domain/path rules match
localStorageClient-side settings such as a themeYes, until code or the user clears itNo
sessionStorageTemporary data for one browser tabNo, it ends when the tab/session endsNo
JavaScript variableData needed only while current code runsNoNo

For a CSS choice controlled entirely in the browser, localStorage is often the most straightforward alternative:

localStorage.setItem("theme", "style-2.css");
const theme = localStorage.getItem("theme");

Choose a cookie when the server needs to know the preference, for example to render the preferred theme before JavaScript runs.

Take Quiz

Cheat Sheet

// Set a cookie for 7 days
const secondsIn7Days = 7 * 24 * 60 * 60;
document.cookie = `theme=${encodeURIComponent("style-2.css")}; max-age=${secondsIn7Days}; path=/; SameSite=Lax`;

// Read all cookies as one string
document.cookie;

// Get one cookie by name
function getCookie(name) {
  const prefix = `${encodeURIComponent(name)}=`;

  for (const part of document.cookie.split(";")) {
    const cookie = part.trim();
    if (cookie.startsWith(prefix)) {
      return decodeURIComponent(cookie.slice(prefix.length));
    }
  }

  return null;
}

// Delete a cookie
function deleteCookie(name) {
  document.cookie = `${encodeURIComponent(name)}=; max-age=0; path=/`;
}

Rules to remember:

  • Separate cookie attributes with ;.
  • Use max-age in seconds for a duration.
  • Use path=/ when all pages should read the cookie.
  • Encode stored names and values.
  • document.cookie returns only cookies available to the current page.
  • Validate a stored value before using it to choose a file or behavior.

FAQ

How do I set a cookie for seven days in JavaScript?

Use max-age with the number of seconds in seven days:

document.cookie = "theme=style-2.css; max-age=604800; path=/";

Why does document.cookie show several values?

A site can have many cookies. JavaScript returns the cookies available to the current page as one semicolon-separated string, so you must search for the name you need.

Can JavaScript read every cookie in the browser?

No. It can only read cookies available to the current page's origin and path. Cookies marked HttpOnly are intentionally unavailable to JavaScript.

Why is my cookie gone after I reload the page?

You may have created a session cookie by omitting max-age or expires, used an expiration date in the past, or created the cookie with a path that does not match the current page.

Should I use a cookie or localStorage for a CSS theme?

Use localStorage when only browser JavaScript needs the preference. Use a cookie when the server also needs to read the preference, such as when it renders the initial page theme.

How do I delete a JavaScript cookie?

Set the same cookie name with max-age=0 and use the same path used when creating it:

document.cookie = "theme=; max-age=0; path=/";

Can I store a CSS file URL in a cookie?

Yes, but only apply values from a known list of stylesheets. This prevents an unexpected or invalid saved value from controlling which resource is loaded.

Take Quiz

Mini Project

Description

Build a theme preference selector for a small website. The visitor chooses one of several CSS files, sees the change immediately, and keeps that choice for seven days. The project demonstrates DOM selection, change events, cookie writing, cookie parsing, and validation of saved data.

Goal

Create a theme picker that restores the last valid stylesheet selected by the visitor.

Requirements

Include a stylesheet <link> element and a <select> with at least three theme options. Change the active stylesheet whenever the visitor selects a new option. Store the selected theme in a cookie that lasts seven days. Restore the saved theme and selected option when the page loads. Apply only theme filenames from an allowed list.

Take Quiz

Keep learning

Related questions

View more