Development

Add a Dark Mode Toggle for Vue.js Apps with Vuetify

A simple way to set Vuetify’s dark mode state and make it user-configurable

H. Kamran

--

Source: Material.io

I use Vue.js and Vuetify for almost all of my websites and I’m a huge supporter of dark mode. I chose Vuetify for many reasons, and out-of-the-box dark mode support is one of them. So, without further ado, let me guide you through changing the dark mode state — easily.

Setting the Default Dark Mode State

In order to set the default dark mode state, we have to open the plugin file for Vuetify, which is available at src/plugins/vuetify.js. By default, the file should look like the following.

import Vue from "vue";
import Vuetify from "vuetify/lib";
Vue.use(Vuetify);export default new Vuetify({});

From here, all we need to do is set the dark parameter to true within the theme object. So our export default statement will become:

export default new Vuetify({
theme: {
dark: true
}
});

But if we want to change it from the user-facing interface, like a toggle or something, we have to use a variable that Vuetify provides.

Setting the Dark Mode State From the Interface

A copy of the final code is available at the bottom.

Before we even add the theme state-changing code, we have to decide where to put the code. You only have to put it in one location, preferably one that is persistent — such as your App.vue, or a component that is present on all pages like a navigation bar. With that decided, we can actually get to work.

In your file (I’m using a component that I’ve called NavigationBar), go to the script tag. There should be an export default statement present. If not, go ahead and create it. Your script should look similar to this:

<script>
export default {
name: "NavigationBar"
}
</script>

First, we need to add the method that will be called when the user clicks on a button. Underneath the name parameter, add a methods object, like so:

export default {
name: "NavigationBar",
methods: {}
}

I’m going to call my method toggle_dark_mode, but feel free to call it whatever you'd like. This method is going to:

  1. Set the dark mode variable (this.$vuetify.theme.dark) to the opposite of whatever it is currently set to (so true if it's false, false if it's true)
  2. Set a local storage variable called dark_theme to the value of that variable. If you'd like to learn more about local storage, check out this article from the MDN Web Docs.

Replace methods: {} with the following:

methods: {
toggle_dark_mode: function() {
this.$vuetify.theme.dark = !this.$vuetify.theme.dark;
localStorage.setItem("dark_theme", this.$vuetify.theme.dark.toString());
}
}

With the toggle function implemented, we now need to create a function to load the data and set it when the page starts. We can have the site automatically pick up the theme state from the browser with the prefers-color-scheme CSS media query (read more) and/or the local storage state. The prefers-color-scheme state is set by your system -- to set the dark mode state on your computer, check out the following guides for macOS or Windows.

To do this, we will use a Vue lifecycle hook named mounted which is called, you guessed it (I hope), when the page is mounted. We'll add mounted() {} underneath the methods object.

export default {
name: "NavigationBar",
methods: {...},
mounted() {}
}

We will first check what the value of our local storage variable is. If it exists, we’ll set this.$vuetify.theme.dark to the value of the variable. If it doesn't, we'll check whether the user has dark mode enabled on their system, and set it to that.

mounted() {
const theme = localStorage.getItem("dark_theme");
if (theme) {
if (theme === "true") {
this.$vuetify.theme.dark = true;
} else {
this.$vuetify.theme.dark = false;
}
} else if (
window.matchMedia &&
window.matchMedia("(prefers-color-scheme: dark)").matches
) {
this.$vuetify.theme.dark = true;
localStorage.setItem(
"dark_theme",
this.$vuetify.theme.dark.toString()
);
}
}

All that’s left is to add a button to toggle the state. I’ll use the Material Design icon theme-light-dark. In my template tag, add the following:

<v-btn icon @click="toggle_dark_mode">
<v-icon>mdi-theme-light-dark</v-icon>
</v-btn>

The code above is simple. It creates a Vuetify icon button, tells it to use the theme-light-dark icon, and to, on click, call the toggle_dark_mode method.

That’s it. You’re finished! If you want to see an example, check out Reprint (unless you’re already reading this article there), or check out my personal website. As I mentioned earlier, the final code is available at this GitHub Gist.

Thanks for reading!

--

--

H. Kamran

I am a developer experienced in Python, JavaScript, Vue.js, Swift, and Git. I write about content that I find interesting or useful to share with the world.