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
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:
- Set the dark mode variable (
this.$vuetify.theme.dark
) to the opposite of whatever it is currently set to (sotrue
if it'sfalse
,false
if it'strue
) - 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!