Skip to content

Astro View Transitions and Dark Mode

New Courses Coming Soon

Join the waiting lists

View Transitions in Astro are amazing, you can see them at work on this blog by clicking a menu item, for example - very smooth transition to other pages of the site, it’s great.

It’s a static site, but navigation feels smooth like in a single-page application.

I noticed a problem when I implemented dark mode in a new theme. Previously I just used the OS default, now I also have a new toggle to choose the mode you prefer.

But, problem: since it was loading the state from session storage in the browser, going to another page re-set that preference to light mode.

I had to use the astro:after-swap event, to call the function that gets the dark mode preference from the session storage also when the page is swapped with a new one in a view transition.

Here’s a link to the docs:

<script is:inline>
  const setDarkMode = () => {
    if (typeof window !== "undefined") {
      const isSystemColorSchemeDark = window.matchMedia(
        "(prefers-color-scheme: dark)"
      const storageTheme = sessionStorage.getItem("theme")
      if (!storageTheme && isSystemColorSchemeDark) {
        document.head.children.namedItem("theme-color").content = "#262626"
      } else if (storageTheme === "dark") {
        document.head.children.namedItem("theme-color").content = "#262626"
      } else {
        // we already server render light theme
        document.head.children.namedItem("theme-color").content = "#ffffff"

  // Runs on initial navigation

  // Runs on view transitions navigation
  document.addEventListener('astro:after-swap', setDarkMode)
→ Read my Astro Tutorial on The Valley of Code

Here is how can I help you: