Alto Theme Custom Dark Mode Toogle

Hi!
I am running https://journeyography.com
Currently, I am using the Alto theme and would like to allow my visitors to switch between light and dark mode using a toggle.
I already implemented a function in my default.hbs:

        function toggleDarkMode() {
            var html = document.querySelector("html");
            if (localStorage.getItem('alto_dark') === null) {
                localStorage.setItem('alto_dark', true);
                html.classList.add('dark-mode');
                document.getElementById('dark_mode').innerHTML = '🌞';
            }
            else {
                localStorage.removeItem('alto_dark');
                html.classList.classList.remove('dark-mode');
                document.getElementById('dark_mode').innerHTML = '🌙';
            }
        }
    ```
However, this does not work as it switches back to light mode after the user moves to another page. Any suggestions?
Thanks!

Do you run the function on page load and not just when the user hits the toggle? That’d be my guess.

Your site is private, so it’s not possible to see how the script is working.

No, the script is called by a button onClick.

Then, you’ll need to also run the script when the page loads. Right now, your function will only run when the user clicks the button. However, you need to run the script when the page loads to see if a preference was set in localStorage. You’ll also want to run this script in head to avoid any jankiness in loading.

Hi Ryan!
I now implemented the changes. I load the script in and when I change a page, I check during window.onload, which value is stored in localstorage. However, if dark mode is enabled, the page first appears in light mode and then switches to dark mode after 0.5s or so. It’s not a deal breaker, but there should be a better way, no?

Are you inlining the script way up in the head section? Not deferred, not loading from a file. Show the code & context around it? Localstorage access is normally pretty fast, so I suspect you’re running it too late in the process if you’re getting an 0.5s lag.

This is my code:

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>{{meta_title}}</title>
    <link rel="stylesheet" href="{{asset "built/screen.css"}}">
    <link rel="stylesheet" href="{{asset "css/darkmode.css"}}">
    <script src="{{asset "js/darkmode.js"}}"></script>
    {{ghost_head}}
</head>

RIght. Don’t do that. Put the code directly into the page.

I would like to avoid that since it is quite a bit of code.

Then it’s going to flicker. The time to open a new connection and read a file is not zero, and it’s almost certainly longer than the time to get a dozen lines of code sent inline at the top of the page.

1 Like

Hey @altotoggle ,

I was looking at Alto for a project and surprised to see it doesn’t have a toggle built in (which is weird, because there’s one in the demo??). I love the styling for the toggle that you’re using. May I steal it? :slight_smile:

Ahha! For anyone who comes after, I suspect it came from here, or one of a couple similar tutorials?