Automatic Dark Mode in Hugo Based on User System

  • YC YC
  • |
  • 07 December 2023
post-thumb

In our previous article, we delved into how we can add dark mode using Hugo. If you missed that insightful read, it is best to catch up before continuing. Now, let’s elevate the user experience by exploring the implementation of automatic dark mode based on user system preferences. In this step-by-step guide, we’ll navigate the steps to integrate this feature seamlessly into your Hugo-powered websites. Let’s dive in!

How we can obtain user system setting

We can obtain the user system setting by using the window.matchMedia() method with the prefers-color-scheme CSS media feature.

Here’s how we can determine the user’s preferred dark theme mode:

const defaultSystemMode = window.matchMedia("(prefers-color-scheme:dark)").matches ? "dark" : "light";

Set theme based on system mode

Continuing from code snippets used in the previous article, let us now introduce automatic dark theme mode by modifying the setThemeMode(mode) method.

// Set theme with the given mode and toggle the theme icon button
function setThemeMode(mode) {
  if (mode === "system") {
    mode = defaultSystemMode
  }

  ...
}

When we invoke setThemeMode("system") on page load, the theme mode will adapt according to the user’s preference.

As we like to only persist the selected theme when user has explicitly toggle the theme button, we simply add a condition before persisting the setting using localStorage.

// Set theme with the given mode and toggle the theme icon button
function setThemeMode(mode) {
  if (mode === "system") {
    mode = defaultSystemMode
  } else {
    // Do not set local storage if user rely on system mode
    localStorage.setItem("dark-mode-theme", mode);
  }

  ...
}

Default mode to user system setting or saved preference

To set the theme automatically during page load, you probably have something like the following

setThemeMode(localStorage.getItem("dark-mode-theme") || "light");

Now to integrate user system setting with their saved preference, we adjust the default to "system" instead.

setThemeMode(localStorage.getItem("dark-mode-theme") || "system");

Putting them together

This is what the final code looks like

const defaultSystemMode = window.matchMedia("(prefers-color-scheme:dark)").matches ? "dark" : "light";

// Set theme with the given mode and toggle the theme icon button
function setThemeMode(mode) {
  if (mode === "system") {
    mode = defaultSystemMode
  } else {
    // Do not set local storage if user rely on system mode
    localStorage.setItem("dark-mode-theme", mode);
  }

  if (mode === "dark") {
    darkCSS.prop('disabled', false)
    $("#dark-toggle i").attr('class', lightIconClass)
  } else if (mode === "light") {
    darkCSS.prop('disabled', true)
    darkToggleIcon.attr('class', darkIconClass)
  }
}

setThemeMode(localStorage.getItem("dark-mode-theme") || "system");

Conclusion

With the implemented code, users will be greeted seamlessly with the theme mode corresponding to their system settings, providing an enhanced browsing experience. This feature is particularly advantageous for users who have configured their machines to enable dark mode during specific periods of the day. Importantly, user preferences will be stored only after they click on the theme toggle, ensuring a personalized and user-friendly interaction with your Hugo website.

comments powered by Disqus

You May Also Like