How to make html and js to remember users dark theme setting

Issue

I am making a website for my discord bot (https://beast-bot.ga) i made a dark theme feature which will switch the website from light mode to dark mode but when i refresh the page the website will switch back to light mode is there any way to fix this like saving the data in a cookie or something.

my js

var icon = document.getElementById("icon");

       icon.onclick = function(){
        document.cookie = "theme=dark";
          document.body.classList.toggle("dark-theme");
          if(document.body.classList.contains("dark-theme")){
             icon.src = "images/sun.png";
          }else{
             icon.src = "images/moon.png"
          }
        }

style.css

* {
  margin: 0;
  padding: 0;
}
@import url("https://fonts.googleapis.com/css2?family=Nunito:wght@700&family=Quicksand:wght@600&display=swap");
@import url("https://fonts.googleapis.com/css?family=Archivo:400,700");
@import url("https://fonts.googleapis.com/css2?family=Oswald&display=swap");
@import url("https://fonts.googleapis.com/css?family=Source+Code+Pro");
@import url("https://fonts.googleapis.com/css2?family=Open+Sans+Condensed:wght@300&display=swap");
/*Desktop*/
:root{

  --normal:url(images/wave-haikei.svg);
  --darks: url(images/wave-black.svg);
  --text-theme: white;
  --cont2: url(images/wave-rot.PNG);
}
.dark-theme{
    --normal: url(images/wave-black.svg);
    --text-theme: white;
    --cont2: url(images/black-wave-rot.svg);
}

/*Desktop reals*/
@media screen and (min-width: 1301px){
  .container {
    height: auto;
    width: 100%;
    background-image: var(--normal);

    background-position: center;
    background-size: cover;
    padding-left: 5%;
    padding-right: 5%;
    box-sizing: border-box;
    position: relative;
  }
  .title {
    font-family: "Quicksand", sans-serif;
    font-size: 72px;
    color: var(--text-theme);
    position: relative;
    top: 200px;
    margin-left: 200px;
    user-select: none;
  }
  /* Add a black background color to the top navigation */
  .topnav {
    background-color: black;
    overflow: hidden;
  }

  /* Style the links inside the navigation bar */
  .topnav a {
    float: left;
    color: #0087ca;
    text-align: center;
    font-family: "Nunito", sans-serif;
    padding: 14px 16px;
    text-decoration: none;
    font-size: 17px;
  }

  /* Change the color of links on hover */
  .topnav a:hover {
    background-color: #ddd;
    color: black;
  }

  /* Add a color to the active/current link */
  .topnav a.active {
    color: #0087ca;
  }
  .title .img {
    width: 400px;
    height: 400px;
    left: 600px;
    bottom: 250px;
    position: relative;
  }
  .infotit {
    font-size: 10px;
    color: var(--text-theme);
  }
  .hover-underline-animation a {
    display: inline-block;
    position: relative;
    color: #0087ca;
  }
  
  .hover-underline-animation a:after {
    content: "";
    position: absolute;
    width: 100%;
    transform: scaleX(0);
    height: 6px;
    bottom: 0;
    left: 0;
    background-color: #0087ca;
    transform-origin: bottom right;
    transition: transform 0.25s ease-out;
  }

  .hover-underline-animation a:hover:after {
    transform: scaleX(1);
    transform-origin: bottom left;
  }
  .trust {
    font-size: 26px;
    font-family: "Quicksand", sans-serif;
    position: relative;
    color: var(--text-theme);
    text-align: center;
  }
  .info .quote {
    font-size: 36px;
    font-family: "Quicksand", sans-serif;
    position: relative;
    text-align: center;
    bottom: 100px;
    color: var(--text-theme);
  }
  .info .btn {
   text-align: center;
    position: relative;
    
  }
  .info .quoto {
    text-align: center;
    font-family: "Quicksand", sans-serif;
    font-size: 36px;
    bottom: 50px;
    position: relative;
    color: var(--text-theme);
  }
  .info .h11 {
    text-align: center;
    position: relative;
    bottom: 20px;
    font-family: "Quicksand", sans-serif;
    font-size: 20px;
    color: var(--text-theme);
  }
  .info .h11 .h33 {
    color: red;
  }
  .info .h11 .muchmore_txt {
    color: red;
  }
  .f_txt {
    font-size: 26px;
    color: var(--text-theme);
  }
  .more_txt {
    font-size: 26px;
    color: var(--text-theme);
  }
  .footer {
    font-family: "Quicksand", sans-serif;
    text-align: center;
    background-color: gray;
    height: 100px;
  }

  /*MORE CONTENTS*/
  .container2 {
    width: 100%;
    height: auto;
    background-image: var(--cont2);
    object-fit: cover;
    background-size: cover;
    background-repeat: no-repeat;
    overflow: auto;
 

  }
  
  .title2 {
    font-size: 10px;
    font-family: "Quicksand", sans-serif;
    color: white;
    text-align: center;
    border-style: groove;
  }
  .hideme {
    opacity: 0;
  }
  .minecraft {
    float: right;
    margin-top: 10%;
    text-align: center;
    font-size: 26px;
    color: white;
    font-family: "Nunito", sans-serif;
  }
  .mcimg {
    width: 605px;
    height: 300px;
    border-color: red;
  }
  .mcpara {
    font-size: 15px;
  }
  .joke {
    float: left;
    margin-top: 40%;
    text-align: center;
    font-size: 26px;
    color: white;
    font-family: "Nunito", sans-serif;
  }
  .jokeimg {
    width: 805px;
    height: 300px;
  }
  .jokepara {
    font-size: 15px;
  }
  .roast {
    float: right;
    margin-top: 40%;
    text-align: center;
    font-size: 26px;
    color: white;
    font-family: "Nunito", sans-serif;
  }
  .roastimg {
    width: 705px;
    height: 300px;
  }
  .roastpara {
    font-size: 15px;
  }
  .animegif {
    float: left;
    margin-top: 40%;
    text-align: center;
    font-size: 26px;
    color: white;
    font-family: "Nunito", sans-serif;
  }
  .animeimg {
    width: 605px;
    height: 300px;
  }
  .animapara {
    font-size: 15px;
  }
  .meme {
    float: right;
    margin-top: 40%;
    text-align: center;
    font-size: 26px;
    color: white;
    font-family: "Nunito", sans-serif;
  }
  .memeimg {
    width: 705px;
    height: 400px;
  }
  .memepara {
    font-size: 15px;
  }

my index.html
https://pastebin.com/jKMT14Nk

Solution

Didn’t tested it. But I guess it should work. So basically what you do is on page load you check if there is an item theme inside of the localstorage that has the value dark if so, you toggle the theme.

Otherwise you toggle the value of the property theme inside of the localstorage, as well as the class on your body and the icon as soon as you click on it. Sadly you didn’t provide any HTML that’s why I couldn’t test it.

This should completely replace the js you posted above.

const themeToggle = document.getElementById("icon");
const darkThemeClass = 'dark-theme';

const toggleTheme = () => {
  setTheme(document.body.classList.contains(darkThemeClass));
}

const setTheme = (theme) => {
  localStorage.setItem('theme', theme ? 'light' : 'dark');
  themeToggle.src =  `images/${!theme ? 'sun' : 'moon'}.png`;
  document.body.classList.toggle(darkThemeClass, !theme);
}

themeToggle.addEventListener('click', toggleTheme);

(() => localStorage.getItem('theme') === 'dark' && setTheme(false))();

Answered By – Quentin Albert

Answer Checked By – David Marino (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.