Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Switching themes

Since the theme is set by the data-theme attribute, switching it means changing that attribute on <html>. You can do it with a couple of lines of JavaScript, or with no JavaScript at all using the theme-controller class.

Switching from JavaScript

A data-* attribute is available in JavaScript through the dataset property. The buttons below write the theme name into document.documentElement.dataset.theme:

<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css">
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
 
<div class="rounded-box bg-base-100 p-4 text-base-content">
  <p class="mb-3">LearnUp dashboard</p>
  <button class="btn btn-sm" data-set-theme="light">Light</button>
  <button class="btn btn-sm" data-set-theme="dark">Dark</button>
</div>
 
<script>
  document.querySelectorAll('[data-set-theme]').forEach((button) => {
    button.addEventListener('click', () => {
      document.documentElement.dataset.theme = button.dataset.setTheme;
    });
  });
</script>

Click "Dark" — the block turns dark with light text; "Light" brings back the original look. The block is repainted because its bg-base-100 and text-base-content classes take their colors from the current theme.

Remembering the choice

To keep the theme after a reload, save the choice in localStorage and restore it when the page opens. In a Vite project create the file src/theme.js:

// src/theme.js
const saved = localStorage.getItem('theme');
if (saved) {
  document.documentElement.dataset.theme = saved;
}
 
document.querySelectorAll('[data-set-theme]').forEach((button) => {
  button.addEventListener('click', () => {
    const theme = button.dataset.setTheme;
    document.documentElement.dataset.theme = theme;
    localStorage.setItem('theme', theme);
  });
});

Import it in src/main.js with import './theme.js';. Now the chosen theme stays after the page is refreshed.

No JavaScript: theme-controller

daisyUI can switch the theme with pure CSS. Give a checkbox or a toggle the theme-controller class and put the theme name into its value attribute. While it is checked, that theme applies to the page:

<link href="https://cdn.jsdelivr.net/npm/daisyui@5" rel="stylesheet" type="text/css">
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
 
<div class="rounded-box bg-base-100 p-4 text-base-content">
  <label class="flex cursor-pointer items-center gap-2">
    Light
    <input type="checkbox" value="dark" class="toggle theme-controller">
    Dark
  </label>
</div>

Click the toggle — the block turns dark. toggle is the switch component, covered in the forms chapter. For several themes, use radio buttons with a shared name, each with its own value.

ApproachProsCons
JavaScript and data-themeCan remember the choiceNeeds a script
theme-controllerNot a line of JSThe choice resets on reload

Common mistake

Restoring the theme only in src/theme.js. Vite loads scripts as modules (type="module"), and modules run after the page has been parsed. So the page shows in the default theme first and only later repaints — the screen visibly "flashes". Move the lines that read localStorage and set data-theme into a small <script> tag right in the <head> of index.html, and keep the button handlers in src/theme.js.

Thanks for reading!

Donate to the site — we work hard for you.