Reputation: 13
I have managed to get a light-dark mode toggle working on my website, but am struggling to figure out how I would implement cookies or localstorage to call upon the user's preferred theme when changing pages on the site.
What I am working with is an external JS file consisting of:
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)');
const toggle = document.querySelector('.toggle');
const html = document.querySelector('html');
html.dataset.dark = localStorage.dark || prefersDarkMode.matches;
toggle.addEventListener('click', () => {
localStorage.dark = !(html.dataset.dark == 'true');
html.dataset.dark = localStorage.dark;
});
Which is then used in the style sheets by choosing between separate styles with:
html[data-dark="false"]{...}
html[data-dark="true"] {...}
I am very new to JS, which I am sure shows, and have only gotten to this point with the help of peers. I've done my best to try solutions from other answers here as well as learn more about localstorage and cookies through resources like the Mozilla docs but am struggling. A solution or being pointed in the right direction would be greatly appreciated, thank you.
Edit: To clarify on what I am trying to achieve; I would like it so that user theme preferences are saved and applied to all pages while what I currently have only saves an individual page's user preferences, meaning they would manual have to toggle them each time.
Upvotes: 1
Views: 1772
Reputation: 91
When using localStorage you opperate with setItem
and getItem
, you can read more about the examples of how to use localStorage here https://developer.mozilla.org/en-US/docs/Web/API/Window/localStorage#examples.
If you want to get/set localStorage item you would use something like this:
// Creates/sets the localStorage item of "theme" to "dark"
localStorage.setItem("theme", "dark")
// Gets the localStorage item named "theme", and checks if the value is "dark"
const isDarkMode = localStorage.getItem("theme") === "dark"
One way of implementing this could be something like this:
// DOM elements
const toggle = document.querySelector(".toggle");
const html = document.querySelector("html");
// Check the browser preferred color scheme, and sets the defaultTheme based of that
const prefersDarkMode = window.matchMedia("(prefers-color-scheme: dark)").matches;
const defaultTheme = prefersDarkMode ? "dark" : "light";
const preferredTheme = localStorage.getItem("theme")
// Check if the localStorage item is set, if not set it to the default theme
if (!preferredTheme) {
localStorage.setItem("theme", defaultTheme);
}
// Sets the theme of the site either the preferredTheme or the defaultTheme (based on localStorage)
html.dataset.theme = preferredTheme || defaultTheme;
// Theme toggle handler
toggle.addEventListener("click", () => {
// Check if the saved theme in localStorage is "dark"
const isDarkTheme = localStorage.getItem("theme") === "dark";
// Chooses the opposite theme of the current selected one
const newTheme = isDarkTheme ? "light" : "dark"
// Changes the theme to the newTheme
localStorage.setItem("theme", newTheme);
html.dataset.theme = newTheme;
});
You would then need to change your data attributes in the css to check for the theme
and not true
or false
like this:
html[data-theme="light"]{...}
html[data-theme="dark"] {...}
Upvotes: 1