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 |
Palette tokens
Functions
createTheme
(_options?: ThemeOptions<ThemeRecord>) => ThemeContext<ThemeTicketInput, ThemeTicket<ThemeTicketInput>>Creates a new theme instance.
createThemeContext
<_E>(_options?: ThemePluginOptions | undefined) => ContextTrinity<_E>createThemePlugin
(_options?: ThemePluginOptions | undefined) => PluginuseTheme
<_E>(namespace?: string) => _EOptions
foreground
boolean | undefinedAutomatically generate `on-*` foreground colors for each theme color using APCA contrast analysis.
rgb
boolean | undefinedOutput CSS variable values as decomposed RGB channels (`R, G, B`) instead of hex strings.
target
string | HTMLElement | null | undefinedThe target element or selector to apply theme classes to.
Properties
selectedValues
ComputedRef<Set<E["value"] extends Ref<infer U, infer U> ? U : E["value"]>>Computed Set of selected ticket values
selectedId
ComputedRef<ID | undefined>selectedIndex
ComputedRef<number>selectedItem
ComputedRef<E | undefined>selectedValue
ComputedRef<E["value"] | undefined>colors
ComputedRef<Record<string, Colors>>A computed reference to the resolved colors of all registered themes.
Methods
move
(id: ID, toIndex: number) => E | undefinedSeek for a ticket based on direction and optional predicate
seek
(direction?: "first" | "last", from?: number, predicate?: (ticket) => boolean) => E | undefinedon
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidListen for registry events
off
<K extends Extensible<RegistryEventName>>(event: K, cb: EventHandler<E, K>) => voidStop listening for registry events
emit
<K extends Extensible<RegistryEventName>>(event: K, data: EventPayload<E, K>) => voidEmit an event with data
batch
<R>(fn: () => R) => RExecute operations in a batch, deferring cache invalidation and event emission until complete
register
(registration?: Partial<Z>) => ERegister a theme with optional colors. When `colors` is provided, onboards them as flat tokens for alias resolution and stores them as the ticket value.