leabs / astro-tailwind-flowbite-template

A base for projects using Astro, Tailwind, and Flowbite UI components
https://astro-portfolio-template-leabs.vercel.app
62 stars 30 forks source link

bug: In dark mode the website refeshes in light mode then switches dark mode (for a split second) after fully loaded #1

Closed leabs closed 11 months ago

leabs commented 1 year ago

Likely due to the JS in src/components/Nav.astro and the function we run to get darkmode to keep while also using the View Transitions API

2a5A1Ghu1 commented 1 year ago

Here is a recording on my computer of the refresh page issue. The transitions work fine for me though.

https://github.com/leabs/astro-tailwind-flowbite-template/assets/13294167/41a482de-8070-4f10-acb6-eb62e0db7bd7

leabs commented 1 year ago

@2a5A1Ghu1 This should be fixed, I incorrectly set the background classes to a div inside body rather than the body element, I also needed to add a new JS event listener function specifically for view transitions: document.addEventListener("astro:page-load", checkTheme);

Please check this link and let me know if its working as expected and then I will merge: https://astro-portfolio-template-git-1darkmode-bug-leabs.vercel.app

commit: https://github.com/leabs/astro-tailwind-flowbite-template/commit/6f02deb01b54328952fc11eae6c08fdc22e9a288

2a5A1Ghu1 commented 1 year ago

You can still see the "light mode" flash on refresh... In some sort of luck the video shows a slow download of the site, my reg job is a trucker and I am tethered to a cell phone. Which shows the dark mode state fires after the dom is fully loaded.

https://github.com/leabs/astro-tailwind-flowbite-template/assets/13294167/3470bea3-ec7d-41ce-b82d-f72ed88bb5d9

Maybe the astro team has this figured out? https://github.com/withastro/docs/blob/b268cae6af9887060f01d31b213c312fe1ce2c3c/src/layouts/MainLayout.astro#L114

leabs commented 1 year ago

I appreciate you bring this up and capturing it. I'm able to replicate it in dev tools by using the throttle setting. And thanks for the link to Astro's doc layout, interesting they put the theme load script right in the head.

2a5A1Ghu1 commented 1 year ago

Ok so I think there really is no way around this unless the state is shared with the server on refresh. For me I like simplicity but there are probably only a couple ways to fix this issue without using some other framework island. Either by setting the state via cookie, url or some HTMX trickery.

I come from the days when browsers asked the server for a specific state(just started webdev again after what 15 years). So my mind set is go the htmx or url var(?dark=true) route and then if need be cookie. That way the state can be returned by the server already initialized. But that is the oldschool php/perl way of doing things. Now we need multiple copies of states hiding in server memory for some odd reason. 🤦‍♂️ 🤷‍♂️

williamneves commented 11 months ago

I found a good solution on the internet

// Get Cookie and set the theme
const theme = Astro.cookies.get("theme")?.value ?? "light"

if you set the theme on the cookie, server can read at build time

<html lang='en' data-theme={theme}>
<script is:inline>
      // Function setTheme receive light or dark as argument and set to document html data-theme
      function setTheme(theme) {
        document.documentElement.setAttribute("data-theme", theme)
      }

      // function setThemeCookie receive light or dark as argument and set to cookie theme and with expiration on 1 year, no path
      function setThemeCookie(theme) {
        document.cookie = `theme=${theme};max-age=31536000;`
      }

      // function handleThemeChange get the #theme-toggle element and on each click event toggle the theme based on the html theme
      function handleThemeChange() {
        const themeToggle = document.querySelector("#theme-toggle")
        themeToggle.addEventListener("click", () => {
          const htmlTheme = document.documentElement.getAttribute("data-theme")
          if (htmlTheme === "light" || !htmlTheme) {
            setTheme("dark")
            setThemeCookie("dark")
          } else {
            setTheme("light")
            setThemeCookie("light")
          }
        })
      }

      handleThemeChange()

      document.addEventListener("astro:after-swap", handleThemeChange)
    </script>

try this code

leabs commented 11 months ago

@williamneves thank you so much for the comment and code! From what I understand the Githubissues.

  • Githubissues is a development platform for aggregating issues.