Dark mode in Nuxt

The first step you want to take is creating your variables for your two modes (or more!). You’ll want to start with a few variables, such as your font and background colors. You’ll need to set these up in your html rather than :root pseudo.

html {
    --font-color: #f2f2f2;
    --background-color: #555;
}

html[theme='dark'] {
    --font-color: #555;
    --background-color: #f2f2f2;
}

Cookies to save the theme

You can use native cookies, but it’s a bit difficult to set them up. There’s a great nuxt library called cookie-universal-nuxt which makes cookies a breeze. You’ll get a little cookie directive, so you can call $cookies and set and get them. If you set the theme when you click your trigger, you’ll also need to update the html dataset for theme.

saveTheme: function() {
    this.$cookies.set("theme", this.form.theme, {
        sameSite: true,
        secure: true
    });

    document.documentElement.dataset["theme"] = this.form.theme;
}

Create your middleware file

Nuxt - Middleware lets you define custom functions that can be run before rendering either a page or a group of pages. If you missed this functionality like I did because you deleted the folder before you read anything, don’t go creating a plugin to do it. This is the perfect way to create a single responsibility file. Create a new file called theme.js. You’ll need to set the default theme to the one you want, in this example I’ve chosen dark as my default theme.

export default function(context) {
  const theme = context.app.$cookies.get("theme");
  context.app.head.htmlAttrs["data-theme"] = theme || "dark";
}

And that’s all it takes! ✨