Skip to main content

Presets & Defaults

Vuetify’s defaults system allows you to set default prop values for components globally or within specific scopes. This eliminates repetitive prop declarations and ensures consistent styling throughout your application.

Component Defaults

Global Defaults

Set default props for all instances of a component:
import { createVuetify } from 'vuetify'

const vuetify = createVuetify({
  defaults: {
    global: {
      ripple: false,
      density: 'comfortable',
    },
    VBtn: {
      color: 'primary',
      variant: 'flat',
      rounded: 'lg',
    },
    VCard: {
      elevation: 2,
      rounded: 'lg',
    },
    VTextField: {
      variant: 'outlined',
      density: 'compact',
      color: 'primary',
    },
  },
})
Now all buttons automatically inherit these defaults:
<!-- These are equivalent -->
<v-btn>Click me</v-btn>
<v-btn color="primary" variant="flat" rounded="lg">Click me</v-btn>

Global Properties

The global key sets defaults that apply to all components:
defaults: {
  global: {
    ripple: false,           // Disable ripple effects globally
    density: 'comfortable',  // Set density for all components
    rounded: 'lg',           // Set border radius for all components
  },
}

Nested Defaults

Define defaults for components nested within other components:
defaults: {
  VCard: {
    elevation: 2,
    rounded: 'lg',
    // Defaults for buttons inside cards
    VBtn: {
      variant: 'text',
      color: 'primary',
    },
    // Defaults for card text
    VCardText: {
      class: 'text-body-1',
    },
  },
  VToolbar: {
    color: 'primary',
    // Buttons in toolbars are different
    VBtn: {
      variant: 'text',
      color: null,  // Inherit from toolbar
    },
  },
}
When a component is nested inside another:
  1. Component-specific defaults apply first
  2. Parent component’s nested defaults apply next
  3. Global defaults apply last
  4. Explicitly set props always take precedence
<v-card>
  <!-- Uses VCard > VBtn defaults -->
  <v-btn>Action</v-btn>
</v-card>

<v-toolbar>
  <!-- Uses VToolbar > VBtn defaults -->
  <v-btn>Menu</v-btn>
</v-toolbar>

Runtime Defaults

Change defaults at runtime using the useDefaults composable:
<template>
  <div>
    <!-- All buttons in this scope will be outlined -->
    <v-btn>Button 1</v-btn>
    <v-btn>Button 2</v-btn>
  </div>
</template>

<script setup>
import { provideDefaults } from 'vuetify'

provideDefaults({
  VBtn: {
    variant: 'outlined',
    color: 'secondary',
  },
})
</script>

Defaults Options

The provideDefaults function accepts options to control inheritance:
provideDefaults(
  {
    VBtn: { color: 'primary' },
  },
  {
    // Disable defaults entirely
    disabled: false,
    
    // Scoped defaults don't merge with parent
    scoped: false,
    
    // Reset to specific ancestor level
    reset: 1,
    
    // Reset to specific root defaults
    root: 'VCard',
  }
)
<script setup>
import { provideDefaults } from 'vuetify'

// Reset 1 level up (ignore immediate parent defaults)
provideDefaults({
  VBtn: { variant: 'text' },
}, { reset: 1 })

// Reset to VCard's defaults (ignore intermediate defaults)
provideDefaults({
  VBtn: { variant: 'text' },
}, { root: 'VCard' })
</script>

Creating Presets

Create reusable preset configurations:
import type { DefaultsOptions } from 'vuetify'

export const materialPreset: DefaultsOptions = {
  global: {
    ripple: true,
    density: 'default',
  },
  VBtn: {
    color: 'primary',
    variant: 'elevated',
    rounded: 'md',
    elevation: 2,
  },
  VCard: {
    elevation: 2,
    rounded: 'lg',
  },
  VTextField: {
    variant: 'filled',
    density: 'default',
  },
  VAppBar: {
    elevation: 4,
  },
}

Common Preset Patterns

Admin Dashboard Preset

export const adminPreset: DefaultsOptions = {
  global: {
    density: 'comfortable',
    rounded: 'md',
  },
  VBtn: {
    variant: 'flat',
    color: 'primary',
  },
  VCard: {
    elevation: 1,
    VCardActions: {
      VBtn: {
        variant: 'text',
      },
    },
  },
  VDataTable: {
    density: 'compact',
    itemsPerPage: 25,
  },
  VTextField: {
    variant: 'outlined',
    density: 'compact',
  },
  VSelect: {
    variant: 'outlined',
    density: 'compact',
  },
}

Marketing Site Preset

export const marketingPreset: DefaultsOptions = {
  global: {
    ripple: true,
    rounded: 'xl',
  },
  VBtn: {
    size: 'large',
    variant: 'flat',
    rounded: 'pill',
    elevation: 0,
  },
  VCard: {
    elevation: 0,
    variant: 'outlined',
    rounded: 'xl',
  },
  VTextField: {
    variant: 'solo',
    rounded: 'pill',
  },
}

Mobile App Preset

export const mobilePreset: DefaultsOptions = {
  global: {
    density: 'comfortable',
    rounded: 'lg',
  },
  VBtn: {
    size: 'large',
    block: true,
    rounded: 'lg',
  },
  VTextField: {
    variant: 'outlined',
    density: 'comfortable',
  },
  VBottomNavigation: {
    grow: true,
  },
  VList: {
    density: 'comfortable',
  },
}

Merging Presets

Combine multiple presets using mergeDeep:
import { mergeDeep } from 'vuetify/util'
import { basePreset } from './presets/base'
import { brandingPreset } from './presets/branding'

const vuetify = createVuetify({
  defaults: mergeDeep(basePreset, brandingPreset, {
    // Additional overrides
    VBtn: {
      elevation: 2,
    },
  }),
})

Default Props Interface

export type DefaultsInstance = {
  [key: string]: undefined | Record<string, unknown>
  global?: Record<string, unknown>
}

export type DefaultsOptions = Partial<DefaultsInstance>

Using Defaults

Accessing Current Defaults

<script setup>
import { injectDefaults } from 'vuetify'

const defaults = injectDefaults()

// Access component defaults
console.log(defaults.value.VBtn)
console.log(defaults.value.global)
</script>

Internal Component Usage

Vuetify components automatically use defaults:
// Inside a component
import { useDefaults } from 'vuetify'

const props = defineProps({ /* ... */ })
const propsWithDefaults = useDefaults(props, 'VBtn')

// propsWithDefaults includes both explicit props and defaults

Best Practices

1

Start with global defaults

Define common patterns in global defaults before creating component-specific ones.
2

Use presets for themes

Create presets for different app sections (admin, public, mobile).
3

Document preset purpose

Clearly explain what each preset is designed for.
4

Avoid deep nesting

Limit nested defaults to 2-3 levels for maintainability.
5

Test thoroughly

Defaults affect many components, so test changes across your app.

Priority Order

Defaults are resolved in this order (highest to lowest priority):
  1. Explicitly set component props
  2. Scoped defaults from provideDefaults
  3. Parent component nested defaults
  4. Component-specific global defaults
  5. Global defaults (global key)
<template>
  <!-- Priority demonstration -->
  <v-btn color="error">     <!-- 1. Explicit prop wins -->
    Error Button
  </v-btn>
  
  <v-btn>                    <!-- Uses defaults cascade -->
    Default Button
  </v-btn>
</template>
Overriding defaults too extensively can make your codebase harder to understand. Use defaults for consistency, not to hide complexity.
Defaults are reactive. Changing them at runtime with provideDefaults immediately updates all affected components.