Search code examples
tailwind-csssveltesveltekit

How can I update class on an element before the website loads (before onMount)?


I added dark mode to my Svelte + Tailwind website. I did this by first checking for the user's preferred (system default) theme, but also added a button to change it anytime. I essentially just update the local storage to either store dark or light and then give or remove the class "dark" from the root html element. I have run into an issue though: I give or remove the "dark" class onMount which means the default light theme flashes for a second (blinding anyone within 10km radius) before it changes to dark theme.

Related code (taken directly from Tailwind dark mode guide):

onMount(() => {
    if (localStorage.theme === 'dark' || (!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
        document.documentElement.classList.add('dark');
        localStorage.theme = 'dark';
    } else {
        document.documentElement.classList.remove('dark');
        localStorage.theme = 'light';
    }
});

My question(s):

Is there a way to run a function that checks localStorage and applies the "dark" class before displaying the initial website?

If there is no way to do what I am trying to do, is there any other way I can implement themes with the page rendering correctly right away?


Solution

  • onMount only runs fairly late on the client.
    You could probably also move the logic to a head script in a layout:

    <svelte:head>
      <script>
        ...
      </script>
    </svelte:head>
    

    Such scripts should execute about as early as they can (but you cannot use Svelte features there).