useTheme
Theme management with multiple themes, CSS custom properties, and token alias resolution.
Installation
Install the Theme plugin in your app’s entry point:
import { createApp } from 'vue'
import { createThemePlugin } from '@vuetify/v0'
import App from './App.vue'
const app = createApp(App)
app.use(
createThemePlugin({
default: 'light',
themes: {
light: {
dark: false,
colors: {
primary: '#3b82f6',
},
},
dark: {
dark: true,
colors: {
primary: '#675496',
},
},
},
})
)
app.mount('#app')Usage
Once the plugin is installed, use the useTheme composable in any component:
<script setup lang="ts">
import { useTheme } from '@vuetify/v0'
const theme = useTheme()
function toggleTheme() {
theme.cycle(['light', 'dark'])
}
</script>
<template>
<div>
<h1>Current Theme: {{ theme.selectedId }}</h1>
<p>Dark mode: {{ theme.isDark ? 'enabled' : 'disabled' }}</p>
<button @click="toggleTheme">Toggle Theme</button>
</div>
</template>Adapters
Adapters let you swap the underlying CSS injection strategy without changing your application code.
| Adapter | Import | Description |
|---|---|---|
V0StyleSheetThemeAdapter | @vuetify/v0 | Injects CSS via adoptedStyleSheets (default, SPA only) |
V0UnheadThemeAdapter | @vuetify/v0/theme/adapters/unhead | Injects CSS via Unhead↗︎ for SSR/SSG |
Both adapters set a data-theme attribute on the root element. Theme CSS is scoped to [data-theme="light"] / [data-theme="dark"] selectors so multiple themes can coexist in the same stylesheet.
When to use each:
V0StyleSheetThemeAdapter(default) — SPAs without SSR. Usesdocument.adoptedStyleSheetsto inject a liveCSSStyleSheet— no DOM<style>element, zero flicker, works well with CSP when configured.V0UnheadThemeAdapter— SSR or SSG (Nuxt, VitePress). Manages the<style>tag anddata-themeattribute via Unhead so the correct theme is rendered in the initial HTML, avoiding a flash of the wrong theme on hydration. Requires@unhead/vue.
Architecture
useTheme extends createSingle for theme selection and createTokens for color resolution:
Reactivity
Theme selection and computed colors are reactive. Switching themes automatically updates CSS variables.
| Property/Method | Reactive | Notes |
|---|---|---|
selectedId | Current theme ID | |
selectedItem | Current theme ticket | |
selectedValue | Current theme colors | |
selectedIndex | Index in registry | |
colors | Resolved colors for all registered themes (keyed by theme ID) | |
isDark | Current theme is dark | |
select(id) | — | Switch to a specific theme by ID |
cycle(ids?) | — | Advance to the next theme. Pass an array to restrict which themes to cycle |
Examples
Color Studio
Color Studio
A theme explorer using createTheme with a shared palette of token aliases. Switch between predefined themes, inspect resolved colors, and register new themes at runtime.
| File | Role |
|---|---|
context.ts | Creates createTheme with palette aliases and four themes |
Preview.vue | Mini app UI that renders using resolved theme colors |
color-studio.vue | Theme selector, swatch grid, and dynamic registration |