show me how to make dark mode for nuxt3 with ssr = true

show me how to make dark mode for nuxt3 with ssr = true but every time I f5 it doesn't get out of sync causing the background to have the wrong color for 1s before returning to the previously set color
2 Replies
kapa.ai
kapa.ai2w ago
Hi @Hùng Lê. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- I'll show you how to implement dark mode in Nuxt 3 with SSR enabled while preventing the flash of incorrect theme (FOUC) that happens on page refresh. Setting up Dark Mode in Nuxt 3 Nuxt UI automatically registers the @nuxtjs/color-mode module for you, which handles dark mode functionality. If you're not using Nuxt UI, you'll need to install this module separately. Basic Implementation First, let's look at how to create a color mode toggle button:
<script setup>
const colorMode = useColorMode()

const isDark = computed({
get() {
return colorMode.value === 'dark'
},
set() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>

<template>
<ClientOnly v-if="!colorMode?.forced">
<UButton
:icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
color="neutral"
variant="ghost"
@click="isDark = !isDark"
/>

<template #fallback>
<div class="size-8" />
</template>
</ClientOnly>
</template>
<script setup>
const colorMode = useColorMode()

const isDark = computed({
get() {
return colorMode.value === 'dark'
},
set() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
})
</script>

<template>
<ClientOnly v-if="!colorMode?.forced">
<UButton
:icon="isDark ? 'i-lucide-moon' : 'i-lucide-sun'"
color="neutral"
variant="ghost"
@click="isDark = !isDark"
/>

<template #fallback>
<div class="size-8" />
</template>
</ClientOnly>
</template>
This example uses the useColorMode composable to toggle between light and dark modes. The ClientOnly wrapper ensures hydration doesn't cause issues with SSR Link to Color Mode docs. Preventing Flash of Incorrect Theme To prevent the flash of incorrect theme on page refresh (F5), you need to ensure the color mode is properly synchronized between the server and client. Here's how to do it: 1. Configure the color mode module in your nuxt.config.ts:
export default defineNuxtConfig({
// If you're using Nuxt UI, it's already included
modules: ['@nuxtjs/color-mode'],
colorMode: {
preference: 'system', // default value
fallback: 'light', // fallback value if not system preference found
classSuffix: '', // This removes the `class` suffix from generated classes
storageKey: 'nuxt-color-mode' // localStorage key
}
})
export default defineNuxtConfig({
// If you're using Nuxt UI, it's already included
modules: ['@nuxtjs/color-mode'],
colorMode: {
preference: 'system', // default value
fallback: 'light', // fallback value if not system preference found
classSuffix: '', // This removes the `class` suffix from generated classes
storageKey: 'nuxt-color-mode' // localStorage key
}
})
2. Add a color-scheme meta tag to your app.vue:
<script setup>
// You can force a specific mode if needed
// const colorMode = useColorMode()
// colorMode.preference = 'dark'
</script>

<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
<script setup>
// You can force a specific mode if needed
// const colorMode = useColorMode()
// colorMode.preference = 'dark'
</script>

<template>
<NuxtLayout>
<NuxtPage />
</NuxtLayout>
</template>
3. Add CSS variables for your theme in your main CSS file:
@import "tailwindcss";
@import "@nuxt/ui";

:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}

.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
@import "tailwindcss";
@import "@nuxt/ui";

:root {
--ui-bg: var(--ui-color-neutral-50);
--ui-text: var(--ui-color-neutral-900);
}

.dark {
--ui-bg: var(--ui-color-neutral-950);
--ui-border: var(--ui-color-neutral-900);
}
This setup uses CSS variables that will be applied immediately when the page loads, preventing the flash of incorrect theme Link to Theme Tokens. Important Note The @nuxtjs/color-mode module will prioritize reading and using the settings in localStorage, regardless of how you set your preference value in the configuration Link to Stack Overflow post. This is why it's important to have the correct fallback value. Using Pre-built Components If you're using Nuxt UI Pro, you can use pre-built components for color mode switching: 1. ColorModeButton:
<template>
<UColorModeButton />
</template>
<template>
<UColorModeButton />
</template>
2. ColorModeSwitch:
<template>
<UColorModeSwitch />
</template>
<template>
<UColorModeSwitch />
</template>
These components handle all the logic for you and are already optimized for SSR Link to ColorModeButton. By following these steps, you'll have a properly functioning dark mode in your Nuxt 3 application with SSR enabled, without the flash of incorrect theme on page refresh. ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai2w ago
<@395818224114991104> Kapa.ai is still learning and improving, please let me know how I did by reacting below.

Did you find this page helpful?