Skip to main content
Vuetify0 is now in alpha!
Vuetify0 Logo
Theme
Mode
Palettes
Accessibility
Vuetify One
Sign in to Vuetify One

Access premium tools across the Vuetify ecosystem — Bin, Play, Studio, and more.

Not a subscriber? See what's included

Theme

Scopes a theme to a component subtree for independently themed sections of your app.


RenderlessIntermediateApr 5, 2026

Usage

Wrap any section of your template in <Theme> to override the active theme for that subtree. Children calling useTheme() will see the scoped theme as the current selection. When no theme prop is provided, it inherits the parent theme — useful for wrapping content that needs the data-theme attribute without changing the active theme.

vue
<script setup lang="ts">
  import { Theme } from '@vuetify/v0'
</script>

<template>
  <Theme theme="dark">
    <!-- Everything here sees "dark" as the active theme -->
    <slot />
  </Theme>
</template>

Anatomy

Anatomy
<script setup lang="ts">
  import { Theme } from '@vuetify/v0'
</script>

<template>
  <!-- Wrapper mode (default) -->
  <Theme theme="dark">
    <div>Dark-scoped content</div>
  </Theme>

  <!-- Polymorphic rendering -->
  <Theme theme="dark" as="section">
    <div>Renders as section element</div>
  </Theme>

  <!-- Renderless mode -->
  <Theme theme="dark" renderless v-slot="{ attrs }">
    <section v-bind="attrs">Custom element</section>
  </Theme>
</template>

Examples

Scoped Override

Nest <Theme> components to create layered theme contexts. Each section applies data-theme to its wrapper, scoping the active theme for that subtree.

FileRole
ThemeCard.vueDisplays theme colors for the given theme prop
scoped-override.vueEntry — sets up themes and nests scoped overrides

Root context (light)

lightlight
primary
secondary
surface
background
Scoped to dark
darkdark
primary
secondary
surface
background
Nested back to light
lightlight
primary
secondary
surface
background
Independent dark scope
darkdark
primary
secondary
surface
background

Recipes

Polymorphic Rendering

Theme extends Atom, so it accepts the as prop to render as any HTML element:

vue
<Theme theme="dark" as="section">
  <!-- renders as <section data-theme="dark"> -->
</Theme>

Renderless Mode

Set renderless to skip the wrapper element. The slot exposes attrs (including data-theme) for you to bind to your own element:

vue
<Theme theme="dark" renderless v-slot="{ attrs }">
  <section v-bind="attrs">
    No extra wrapper div
  </section>
</Theme>

Isolated Context

By default, <Theme> provides its context under the 'v0:theme' key — the same key used by useTheme(). If you’re building a component that needs its own theme scope that doesn’t interfere with the app’s global theme, pass a custom namespace:

vue
<template>
  <!-- Isolated: useTheme() in descendants won't affect the global theme -->
  <Theme theme="dark" namespace="my-widget:theme">
    <slot />
  </Theme>
</template>
Tip

The namespace prop is only needed when building reusable components that must be theme-isolated. Most apps don’t need it.

Slot Props

The default slot exposes theme (the active ID), isDark (boolean), and attrs for conditional rendering:

vue
<Theme v-slot="{ theme, isDark }" theme="dark">
  <span>{{ theme }} — dark: {{ isDark }}</span>
</Theme>

API Reference

The following API details are for all variations of the Theme component.

Theme

Props

namespace

string | undefined

Default: "v0:theme"

Slots

default

ThemeSlotProps
Was this page helpful?

© 2016-1970 Vuetify, LLC
Ctrl+/