Guide
Theming
Customize colors and dark mode in your UNuxt application
UNuxt uses Nuxt UI v4 with Tailwind CSS v4 for a flexible theming system.
Toggle dark mode
Use the built-in color mode composable:
components/ThemeToggle.vue
<script setup lang="ts">
const colorMode = useColorMode()
function toggleTheme() {
colorMode.preference = colorMode.value === 'dark' ? 'light' : 'dark'
}
</script>
<template>
<UButton
:icon="colorMode.value === 'dark' ? 'i-lucide-sun' : 'i-lucide-moon'"
variant="ghost"
@click="toggleTheme"
/>
</template>
Customize primary colors
Configure your color palette in the app config:
app.config.ts
export default defineAppConfig({
ui: {
colors: {
primary: 'emerald',
neutral: 'zinc'
}
}
})
Available color options: red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose.
Create custom color themes
Define custom colors using OKLCH in your CSS:
assets/css/main.css
@import "tailwindcss";
@import "@nuxt/ui";
@theme static {
--color-primary-50: oklch(0.97 0.02 160);
--color-primary-100: oklch(0.94 0.04 160);
--color-primary-200: oklch(0.88 0.08 160);
--color-primary-300: oklch(0.78 0.12 160);
--color-primary-400: oklch(0.68 0.16 160);
--color-primary-500: oklch(0.55 0.18 160);
--color-primary-600: oklch(0.48 0.16 160);
--color-primary-700: oklch(0.40 0.14 160);
--color-primary-800: oklch(0.33 0.12 160);
--color-primary-900: oklch(0.27 0.10 160);
--color-primary-950: oklch(0.18 0.08 160);
}
Save user theme preferences
Store user preferences and apply them on load:
composables/useTheme.ts
export function useTheme() {
const colorMode = useColorMode()
const primaryColor = useState('primaryColor', () => 'emerald')
function setTheme(color: string, mode: 'light' | 'dark') {
primaryColor.value = color
colorMode.preference = mode
// Persist to user settings
$fetch('/api/user/preferences', {
method: 'PATCH',
body: { theme: { color, mode } }
})
}
return { primaryColor, colorMode, setTheme }
}
Create a theme selector
Build a UI for users to choose their theme:
components/ThemeSelector.vue
<script setup lang="ts">
const { primaryColor, colorMode, setTheme } = useTheme()
const colors = [
{ label: 'Emerald', value: 'emerald' },
{ label: 'Blue', value: 'blue' },
{ label: 'Purple', value: 'purple' },
{ label: 'Rose', value: 'rose' }
]
</script>
<template>
<div class="space-y-4">
<UFormField label="Color">
<USelectMenu
v-model="primaryColor"
:options="colors"
option-attribute="label"
value-attribute="value"
@update:model-value="(v) => setTheme(v, colorMode.preference)"
/>
</UFormField>
<UFormField label="Mode">
<UButtonGroup>
<UButton
:variant="colorMode.preference === 'light' ? 'solid' : 'outline'"
@click="setTheme(primaryColor, 'light')"
>
Light
</UButton>
<UButton
:variant="colorMode.preference === 'dark' ? 'solid' : 'outline'"
@click="setTheme(primaryColor, 'dark')"
>
Dark
</UButton>
</UButtonGroup>
</UFormField>
</div>
</template>