I love dark mode. With a few exceptions, all of the websites I visit, program, or use as apps on my iPhone have dark mode enabled. When it comes to Nuxt 3, my favorite front-end meta-framework, it can only be just a setting in the nuxt.conf.ts
file.
Or not?
Well, that’s what I thought, to be honest. Nuxt is famous for its great developer experience (DX), and I’d say it’s the most intuitive full-stack JavaScript framework out there.
tl;dr
export default defineNuxtPlugin((nuxtApp) => {
const colorMode = useColorMode()
nuxtApp.hook('app:mounted', () => {
colorMode.preference = 'light'
colorMode.value = 'light'
})
})
TypeScriptThe Problem
I’m working on a site where—for a change—I’d like to turn the dark mode off. However, the default settings enabled the dark mode, so I had to find out how to disable it.
As said, I was expecting a single option in the nuxt.conf.ts
, or even app.conf.ts
, but neither of those was the case. Alright, I thought, then let’s head to NuxtUI’s documentation. Documentations by Nuxt are usually concise and make it easy to digest even difficult topics.
So, I headed there and found: nothing. GPT-4o and even o1 couldn’t help me either, so I had to do it the old way: Google.
I stumbled upon this easy and makes-sense code for the aforementioned nuxt.conf.ts
, but this didn’t solve the issue:
// NOT working in NuxtUI v2
colorMode: {
preference: 'light'
}
TypeScriptThe Solution
I found the solution in NuxtUI’s GitHub repository. An issue, marked for some reason as “question,” dating back to May 2023 but has been updated in November 2024, had the answer.
Specifically, user xak2000 came up with the easy but in my eyes still odd solution:
- Create a folder named
plugins
in your Nuxt’s root directory - Create a file, either a
.js
or a.ts
one, and register it as a Nuxt plugin with the following code:
export default defineNuxtPlugin((nuxtApp) => {
const colorMode = useColorMode()
nuxtApp.hook('app:mounted', () => {
colorMode.preference = 'light'
colorMode.value = 'light'
})
})
TypeScriptI added a few inline documentation, because I like documented code, so the file in /plugins/disableDarkMode.client.ts
looks like this in my project:
/**
* Nuxt.js plugin to set the color mode to 'light' when the app is mounted.
*
* @param {Object} nuxtApp - The Nuxt application instance.
*/
export default defineNuxtPlugin((nuxtApp) => {
// Get the color mode object from the useColorMode composable
const colorMode = useColorMode()
// Hook into the 'app:mounted' event to set the color mode to 'light'
nuxtApp.hook('app:mounted', () => {
colorMode.preference = 'light'
colorMode.value = 'light'
})
})
TypeScriptxak2000 and johnnyicon in the comment below explained in relatively great detail why this is necessary. I’ll quote the main part of why Nuxt needs a plugin to disable Tailwind’s dark mode:
The problem with this solution is that if some user already opened the page with
system
color mode (i.e. before changing this config), it is already saved into thelocalStorage
of the user’s browser and this value from the local storage has precedence over the value we set in the nuxt config. So, it is not really “force disable”.The solution described here is not practical in this case because there is no one central place to call
definePageMeta
that every page will respect. Using a layout could help, butdefinePageMeta
is not allowed to be used in layouts. It can be used only in pages.