Search code examples
javascriptnuxt.jstailwind-cssnuxt3.jsdarkmode

Dark mode switcher in Nuxt 3 not working with official @nuxtjs/color-mode


I wanted to implement dark mode on my Nuxt app using tailwind and the recommended @nuxtjs/color-mdoe module. Testing tailwind's dark: classes went fine and worked as expected, however I can't make a button switcher work to set the color mode programmatically.

I installed in devDeps the module in version 3.2.0, which should be compatible with Nuxt 3, according to the docs

"@nuxtjs/tailwindcss": "^6.1.3",
"@nuxtjs/color-mode": "^3.2.0"

And applied the proper configuration in nuxt.config.ts

modules: [ '@nuxtjs/color-mode' ],
colorMode: {
    classSuffix: '',
    preference: 'system',
    fallback: 'dark'
  }

I used tailwind nuxt module In tailwind.config.js

module.exports= {
  theme: {
    colors: {
      transparent: 'transparent',
      current: 'currentColor',
      dark: '#212129',
      darkPrimary: '#00E1FF',
      darkSecondary: '#00D6D6',
      light: '#E9DAC1',
      lightPrimary: '#1d68f3',
      lightSecondary: '#00b5f0',
      main: '#0073FF',
      white: '#FFFFFF',
    },
    spacing: {
      'header': '120px',
    },
    darkMode: 'class'
  }
}

While in ./assets/css/main.css I have no meaningful config about dark mode, just some classes I defined globally

html {
  @apply transition-colors ease-in duration-1000;
  @apply bg-gradient-to-b bg-no-repeat w-screen ;
  @apply dark:from-dark/95 dark:via-dark/95 dark:to-dark dark:text-white from-white via-light/50 to-light;
}

.contain {
  @apply px-[5%] md:px-[25%];       
}

Since I wanted to place the switch in the header here's what I did in the component:

<template>
  <header class="contain py-[15px] flex items-center justify-between backdrop-blur-3xl">
    <button @click="toggleDarkMode($colorMode.preference === 'dark' ? 'light' : 'dark')">
      <nuxt-icon v-if="$colorMode.preference === 'dark'" name="sun"/>
      <nuxt-icon v-else name="moon"/>
    </button>
  </header>
</template>

<script setup>
function toggleDarkMode(theme) {
  useColorMode().preference = theme
}
</script>

The classes are actually toggling when I manually change the color mode from my os (win11) settings, but clicking the button won't replicate the same behavior. The mode seems to be switching since the icon does change accordingly.

Looking at the docs and tutorials I found elsewhere it should just work like that.
Do I need to set the mode as a global state inside the store? Should I call the hook in a root-level component?


Solution

  • ok, there are several mistakes:

    package.json

    my package.json file content is this:

    i think your tailwind version is 3.1.6

    "devDependencies": {
        "@nuxtjs/color-mode": "^3.2.0",
        "autoprefixer": "^10.4.13",
        "nuxt": "3.0.0",
        "postcss": "^8.4.19",
        "tailwindcss": "^3.2.4"
      }
    

    tailwind.config.js

    there are mistakes in your tailwind.config.js file:

    /** @type {import('tailwindcss').Config} */
    module.exports = {
      content: ['./app.vue'], // you forget content
      darkMode: 'class', //you should define darkMode here
      theme: {
        extend: {},
       //darkMode: 'class' >> this is mistake
      },
      plugins: [],
    };
    
    

    first, you forget the content property you should get this warn:

    warn - The content option in your Tailwind CSS configuration is missing or empty.

    what is content:

    The content section of your tailwind.config.js file is where you configure the paths to all of your HTML templates, JavaScript components, and any other source files that contain Tailwind class names.

    second, your darkMode shouldn't be the property of theme you should define it in the root

    main.css

    now about your main.css file you didn't add tailwind directives( but this is not necessary) :

    @tailwind base;
    @tailwind components;
    @tailwind utilities;
    
    @layer base {
      body{
        @apply bg-lightPrimary dark:bg-darkPrimary;
      }
    }
    

    nuxt.config.ts

    Finally, your nuxt.config.ts should be this:

    // https://v3.nuxtjs.org/api/configuration/nuxt.config
    export default defineNuxtConfig({
      modules: ['@nuxtjs/color-mode'],
      colorMode: {
        classSuffix: '',
        preference: 'system',
        fallback: 'dark',
      },
      css: ['/assets/css/main.css'],
      postcss: {
        plugins: {
          tailwindcss: {},
          autoprefixer: {},
        },
      },
    });
    

    I copied your codes and tested them I think your main mistake is that you define darkMode property in the wrong place:

    PLS CHECK THIS LINK

    summary

    1. check tailwind installation here
    2. add darkMode: 'class' correctly
    3. check content property (read more here)
    4. make sure you added main.css file to nuxt.config.ts globally

    these two questions can help you too:

    Install tailwind in nuxt3

    better dark mode configuration