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=604800keeps 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:
- The visitor selects a stylesheet.
- JavaScript changes the
<link>element'shref. - JavaScript saves the selected filename in a cookie.
- 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.
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:
getCookie("theme")reads the fulldocument.cookiestring.- It splits the string into individual cookie entries.
- It finds the entry beginning with
theme=. - It returns
style-3.cssand assigns it tosavedTheme. - The
if (savedTheme)condition is true because the string is not empty. - The
<link id="css">element getshref="style-3.css", so the browser loads that stylesheet. - The
<select>value is changed tostyle-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.
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
| Option | Best for | Persists after browser restart? | Sent to the server automatically? |
|---|---|---|---|
| Cookie | Small preferences a server may need | Yes, if it has an expiry or max-age | Yes, when its domain/path rules match |
localStorage | Client-side settings such as a theme | Yes, until code or the user clears it | No |
sessionStorage | Temporary data for one browser tab | No, it ends when the tab/session ends | No |
| JavaScript variable | Data needed only while current code runs | No | No |
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.
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-agein seconds for a duration. - Use
path=/when all pages should read the cookie. - Encode stored names and values.
document.cookiereturns 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.
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.
Keep learning
Related questions
Add a Favicon to a Static HTML Page
Learn how to add a favicon to static HTML pages, use correct paths and icon formats, and troubleshoot browser caching and local-file issues.
Allow Only Numeric Input (0-9) in HTML Input Using jQuery
Learn how to allow only digits 0-9 in an HTML input using jQuery, with examples, validation tips, common mistakes, and best practices.
Apply CSS !important with jQuery .css()
Learn why jQuery .css() cannot set !important and how to use CSSStyleDeclaration.setProperty() to apply inline important styles safely.