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?
ok, there are several mistakes:
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"
}
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
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;
}
}
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
darkMode: 'class'
correctlycontent
property (read more here)main.css
file to nuxt.config.ts
globallythese two questions can help you too: