# Vuetify User Guide

Vuetify is a **Vue 3 Material Design component framework**. It ships more than one
hundred ready-made UI components — buttons, forms, data tables, dialogs, navigation,
pickers, and more — together with a reactive system for theming, responsive breakpoints,
icons, internationalization, and global configuration. You write Vue templates with
components like `<v-btn>` and `<v-text-field>`, and Vuetify handles the styling,
accessibility scaffolding, and Material Design behavior.

This guide covers everything you need to **install Vuetify, configure it, and use its
components and features** in a real application. It is built from the framework's source
code at version `4.1.0`, so every option, breakpoint, color, and command below reflects
what the code actually does.

> [!NOTE]
> Vuetify 4 requires **Vue 3.5.0 or later** and **Node.js 24.11.1+** for local
> development tooling. It is published under the MIT license.

---

## Table of Contents

1. [Quick Start](#1-quick-start)
2. [Installation](#2-installation)
3. [Core Concepts](#3-core-concepts)
4. [The Application Layout](#4-the-application-layout)
5. [Theme & Colors](#5-theme--colors)
6. [Display & Breakpoints](#6-display--breakpoints)
7. [Icons](#7-icons)
8. [Global Defaults](#8-global-defaults)
9. [Blueprints](#9-blueprints)
10. [Internationalization & RTL](#10-internationalization--rtl)
11. [Dates](#11-dates)
12. [The Component Catalog](#12-the-component-catalog)
13. [Forms & Validation](#13-forms--validation)
14. [Directives](#14-directives)
15. [Programmatic Scrolling](#15-programmatic-scrolling)
16. [Styling, Utility Classes & SASS](#16-styling-utility-classes--sass)
17. [Tree-Shaking & Production Builds](#17-tree-shaking--production-builds)
18. [Server-Side Rendering (SSR)](#18-server-side-rendering-ssr)
19. [Troubleshooting](#19-troubleshooting)
20. [Frequently Asked Questions](#20-frequently-asked-questions)
21. [Reference](#21-reference)

---

## 1. Quick Start

The fastest path to a running Vuetify app is the official scaffolding tool,
**create-vuetify**. It generates a complete Vite + Vue 3 + Vuetify project with sensible
defaults.

=== "pnpm"

    ```bash
    pnpm create vuetify
    ```

=== "npm"

    ```bash
    npm create vuetify@latest
    ```

=== "yarn"

    ```bash
    yarn create vuetify
    ```

=== "bun"

    ```bash
    bun create vuetify
    ```

The tool prompts you for a project name, whether to use TypeScript, and which package
manager to install with:

```text
success Installed "create-vuetify@x.x.x" with binaries:
    - create-vuetify

? Project name: ❯ vuetify-project
? Use TypeScript?: ❯ No / Yes
? Would you like to install dependencies with yarn, npm, or pnpm?:
  ❯ yarn
    npm
    pnpm
    bun
    none
```

Once the scaffold finishes, start the dev server:

```bash
cd vuetify-project
pnpm dev
```

```text
  VITE v7.x  ready in 412 ms

  ➜  Local:   http://localhost:3000/
  ➜  Network: use --host to expose
```

Open the printed URL and you have a working Vuetify application. Every component, the
theme system, and the icon set are already wired up.

> [!TIP]
> `create-vuetify` is the recommended starting point for new projects. If you are adding
> Vuetify to an **existing** project, follow the [manual installation](#existing-projects)
> steps instead.

---

## 2. Installation

Vuetify supports many environments. Pick the one that matches your project.

### Using Vite (recommended)

Use `create-vuetify` as shown in the [Quick Start](#1-quick-start). This sets up Vite, the
`vite-plugin-vuetify` for automatic tree-shaking, fonts, and icons for you.

### Using Nuxt 3

You can either use the dedicated module or wire Vuetify in manually.

**Manual setup.** Create a Nuxt app, then add Vuetify and the Vite plugin as dev
dependencies plus an icon font:

=== "pnpm"

    ```bash
    pnpx nuxi@latest init <project-name>
    cd <project-name>
    # Create a .npmrc file with shamefully-hoist=true
    pnpm install
    pnpm i -D vuetify vite-plugin-vuetify
    pnpm i @mdi/font
    ```

=== "npm"

    ```bash
    npx nuxi@latest init <project-name>
    cd <project-name>
    npm install
    npm i -D vuetify vite-plugin-vuetify
    npm i @mdi/font
    ```

Add the plugin to `nuxt.config.ts`:

```ts
import vuetify, { transformAssetUrls } from 'vite-plugin-vuetify'

export default defineNuxtConfig({
  build: {
    transpile: ['vuetify'],
  },
  vite: {
    plugins: [
      // @ts-expect-error
      vuetify({ autoImport: true }),
    ],
    vue: {
      template: {
        transformAssetUrls,
      },
    },
  },
})
```

Initialize Vuetify as a Nuxt plugin in `~/plugins/vuetify.ts`:

```ts
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'

export default defineNuxtPlugin((app) => {
  const vuetify = createVuetify({
    // ... your configuration
  })
  app.vueApp.use(vuetify)
})
```

Finally, wrap your app in the root `<v-app>` component in `~/app.vue` or
`~/layouts/default.vue`:

```html
<template>
  <NuxtLayout>
    <v-app>
      <NuxtPage />
    </v-app>
  </NuxtLayout>
</template>
```

> [!TIP]
> The opinionated [vuetify-nuxt-module](https://github.com/vuetifyjs/nuxt-module) (Vite
> only) works out of the box with zero configuration for most use cases.

### Using Laravel

As long as you chain `.use()` on your Vue app, Vuetify registers correctly. In
`resources/js/app.ts`:

```js
import { createApp } from 'vue'
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'

const app = createApp()
const vuetify = createVuetify()
app.use(vuetify).mount('#app')
```

And add the Vite plugin to `vite.config.ts`:

```ts
import vuetify from 'vite-plugin-vuetify'

export default defineConfig({
  plugins: [
    vuetify({ autoImport: true }),
  ],
})
```

> [!WARNING]
> If a font is defined in `resources/views/app.blade.php`, Vuetify's own font settings
> will not take effect.

### Using a CDN

For quick prototypes with no build tooling, load the precompiled CSS and JS bundles from
jsDelivr. All components and styles are included.

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@4.1.0/dist/vuetify.min.css" />
  </head>
  <body>
    <div id="app">
      <v-app>
        <v-container>
          <v-text-field label="My field" />
        </v-container>
      </v-app>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/vuetify@4.1.0/dist/vuetify.min.js"></script>
    <script>
      const { createApp } = Vue
      const { createVuetify } = Vuetify
      const vuetify = createVuetify()
      const app = createApp()
      app.use(vuetify).mount('#app')
    </script>
  </body>
</html>
```

### Using an ES Module with a CDN

With an [import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap)
you can use Vuetify as native ES modules without a bundler. Note the bundle is
`vuetify.esm.js`, **not** `.min.js`:

```html
<head>
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@4.1.0/dist/vuetify.min.css" />
  <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@mdi/font@latest/css/materialdesignicons.min.css" />
  <link rel="stylesheet" href="https://fonts.bunny.net/css?family=roboto:400,500,700" />
  <script type="importmap">
  {
    "imports": {
      "vue": "https://cdn.jsdelivr.net/npm/vue@latest/dist/vue.esm-browser.js",
      "vuetify": "https://cdn.jsdelivr.net/npm/vuetify@4.1.0/dist/vuetify.esm.js"
    }
  }
  </script>
</head>
```

### Using VitePress

After initializing a VitePress project, add Vuetify and register it in
`.vitepress/theme/index.ts`:

```ts
import DefaultTheme from 'vitepress/theme'
import 'vuetify/styles'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import { createVuetify } from 'vuetify'

const vuetify = createVuetify({ components, directives })

export default {
  extends: DefaultTheme,
  enhanceApp({ app }) {
    app.use(vuetify)
  },
}
```

### Existing projects

To add Vuetify to an existing project without scaffolding, install the package:

=== "pnpm"

    ```bash
    pnpm i vuetify
    ```

=== "npm"

    ```bash
    npm i vuetify
    ```

=== "yarn"

    ```bash
    yarn add vuetify
    ```

=== "bun"

    ```bash
    bun add vuetify
    ```

Then register it where you create the Vue app:

```js
import { createApp } from 'vue'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import App from './App.vue'

const vuetify = createVuetify({
  components,
  directives,
})

createApp(App).use(vuetify).mount('#app')
```

> [!IMPORTANT]
> Importing **all** components and directives like this is convenient but increases your
> bundle size during development. For production, prefer the
> [Vite plugin with `autoImport`](#17-tree-shaking--production-builds) so only the
> components you actually use are bundled.

### Fonts

Vuetify uses **Roboto** as its default font. You must add it yourself. The recommended
approach uses `@fontsource/roboto`:

=== "pnpm"

    ```bash
    pnpm i @fontsource/roboto
    ```

=== "npm"

    ```bash
    npm i @fontsource/roboto
    ```

Then import the weights you need in `main.ts`:

```js
import '@fontsource/roboto/100.css'
import '@fontsource/roboto/300.css'
import '@fontsource/roboto/400.css'
import '@fontsource/roboto/500.css'
import '@fontsource/roboto/700.css'
import '@fontsource/roboto/900.css'
```

A cleaner alternative bundles fonts with `unplugin-fonts` so they are downloaded once at
build time. See the [Reference](#21-reference) for the `vite.config.ts` snippet.

---

## 3. Core Concepts

### The `createVuetify` plugin

Everything starts with `createVuetify()`. It returns a Vue plugin that you register with
`app.use()`. Internally, it builds the framework's reactive subsystems and provides them to
every component in your app:

```js
import { createVuetify } from 'vuetify'

const vuetify = createVuetify({
  theme:   { /* ... */ },   // colors, light/dark
  display: { /* ... */ },   // responsive breakpoints
  icons:   { /* ... */ },   // icon sets and aliases
  locale:  { /* ... */ },   // translations and RTL
  date:    { /* ... */ },   // date adapter for pickers
  defaults:{ /* ... */ },   // global prop defaults
  blueprint: /* ... */,     // a preset bundle of the above
  ssr: true,                // enable when server-rendering
})
```

When the plugin installs, it registers your components and directives globally and exposes
a single `$vuetify` object on every component instance, with `defaults`, `display`,
`theme`, `icons`, `locale`, and `date`.

> [!NOTE]
> The full list of options is `aliases`, `blueprint`, `components`, `date`, `directives`,
> `defaults`, `display`, `goTo`, `theme`, `icons`, `locale`, and `ssr`. Each one is
> described in its own section of this guide and summarized in the
> [Admin Guide configuration reference](vuetifyjs__vuetify__AdminGuide.md).

### Accessing framework state in your components

Every subsystem has a composable you can call from `<script setup>`. They return reactive
objects:

```vue
<script setup>
import { useTheme } from 'vuetify'
import { useDisplay } from 'vuetify'

const theme = useTheme()
const { mobile, mdAndUp } = useDisplay()
</script>
```

> [!CAUTION]
> These composables must be called during a component's `setup()`. Calling `useTheme()`
> or `useDisplay()` outside of a component (for example, in a plain module) throws
> *"Could not find Vuetify … injection"* because the injection context does not exist
> there.

---

## 4. The Application Layout

Vuetify provides a coordinated **layout system**. The root component is `<v-app>`; every
other layout component registers itself with it so that app bars, drawers, and footers
automatically reserve space and never overlap your main content.

| Component | Role |
|-----------|------|
| `<v-app>` | **Required root.** Wraps the whole UI and hosts theme + layout state. |
| `<v-main>` | The content area that flexes around bars and drawers. |
| `<v-app-bar>` | Top (or bottom) application toolbar. |
| `<v-system-bar>` | Slim status bar above the app bar. |
| `<v-navigation-drawer>` | Side navigation panel (left/right, permanent/temporary). |
| `<v-footer>` | Bottom footer; can be made `app` to integrate with the layout. |
| `<v-layout>` / `<v-layout-item>` | Lower-level building blocks for custom layouts. |

A typical shell looks like this:

```vue
<template>
  <v-app>
    <v-app-bar title="My Application" />

    <v-navigation-drawer>
      <v-list>
        <v-list-item title="Dashboard" to="/" />
        <v-list-item title="Settings" to="/settings" />
      </v-list>
    </v-navigation-drawer>

    <v-main>
      <v-container>
        <router-view />
      </v-container>
    </v-main>

    <v-footer app>© 2026 My Company</v-footer>
  </v-app>
</template>
```

> [!IMPORTANT]
> Wrap your application in exactly **one** `<v-app>`. Many components — overlays, menus,
> dialogs, theming — depend on the providers that `<v-app>` and the `createVuetify` plugin
> set up. Without it, layout offsets and theme classes will not apply correctly.

> [!TIP]
> Put page content inside `<v-container>` (centered, responsive gutters), then use
> `<v-row>` and `<v-col>` for the 12-column grid. See
> [The Component Catalog → Grid & Layout](#grid--layout).

---

## 5. Theme & Colors

Vuetify ships a complete theming engine. It generates CSS custom properties for a palette
and exposes a reactive API to switch themes at runtime.

### Built-in themes

Two themes are defined out of the box: `light` and `dark`. The **default theme is
`system`**, which automatically follows the operating system's
`prefers-color-scheme` setting and switches live when the user changes it.

```js
const vuetify = createVuetify({
  theme: {
    defaultTheme: 'dark', // 'light' | 'dark' | 'system' | your custom name
  },
})
```

The default light and dark palettes (exact values from source) include:

| Token | Light | Dark |
|-------|-------|------|
| `background` | `#FFFFFF` | `#121212` |
| `surface` | `#FFFFFF` | `#212121` |
| `primary` | `#1867C0` | `#2196F3` |
| `secondary` | `#48A9A6` | `#54B6B2` |
| `success` | `#4CAF50` | `#4CAF50` |
| `info` | `#2196F3` | `#2196F3` |
| `warning` | `#FB8C00` | `#FB8C00` |
| `error` | `#B00020` | `#CF6679` |

### Defining a custom theme

```js
const vuetify = createVuetify({
  theme: {
    defaultTheme: 'myTheme',
    themes: {
      myTheme: {
        dark: false,
        colors: {
          primary: '#1976D2',
          secondary: '#424242',
          surface: '#FFFFFF',
          background: '#F5F5F5',
          error: '#FF5252',
        },
      },
    },
  },
})
```

Each color you declare produces matching utility classes (`bg-primary`, `text-primary`,
`border-primary`) and a contrasting `on-` color (for example `on-primary`) is computed
automatically based on luminance so text stays legible on any background.

> [!TIP]
> You do not have to define `on-primary`, `on-surface`, etc. Vuetify derives them for you
> using the theme's `theme-on-light` / `theme-on-dark` variables. Override one only if you
> want a specific contrast color.

### Switching themes at runtime

`useTheme()` returns the theme instance with these methods:

```vue
<script setup>
import { useTheme } from 'vuetify'

const theme = useTheme()

function toggle () {
  theme.toggle()                 // swap between ['light', 'dark']
}

function goDark () {
  theme.change('dark')           // switch to a named theme
}

function next () {
  theme.cycle(['light', 'dark', 'myTheme'])  // rotate through a list
}
</script>

<template>
  <v-btn @click="toggle">Toggle theme</v-btn>
  <div>Current theme: {{ theme.name.value }}</div>
</template>
```

| Method | Behavior |
|--------|----------|
| `change(name, transition?)` | Switch to a named theme. Warns if the name is unknown. |
| `toggle(['a','b']?, transition?)` | Cycle between two themes (defaults to `light`/`dark`). |
| `cycle([names]?, transition?)` | Advance to the next theme in a list, wrapping around. |
| `setTransitionOrigin(event)` | Set the origin point for the animated theme transition. |

Useful reactive properties on the instance include `name` (current theme name), `current`
(the resolved theme definition), `themes` (all definitions), `isSystem` (whether following
the OS), and `global.name`.

### Animated theme transitions

Set `transition: true` to animate theme changes with a circular reveal using the View
Transitions API (where the browser supports it). You can also pass per-change options:

```js
createVuetify({
  theme: {
    transition: { duration: '500ms' },
  },
})
```

```js
theme.setTransitionOrigin(pointerEvent) // start the reveal where the user clicked
theme.toggle(undefined, true)
```

> [!NOTE]
> The transition automatically respects the user's `prefers-reduced-motion` setting and
> falls back to an instant switch when reduced motion is requested or the browser lacks
> `document.startViewTransition`.

### Color variations

You can auto-generate lighter and darker shades of named colors:

```js
createVuetify({
  theme: {
    variations: {
      colors: ['primary', 'secondary'],
      lighten: 3,   // generates primary-lighten-1..3
      darken: 2,    // generates primary-darken-1..2
    },
  },
})
```

### Content Security Policy

If your site uses a CSP nonce, pass it so the injected `<style>` element is allowed:

```js
createVuetify({ theme: { cspNonce: 'your-nonce' } })
```

---

## 6. Display & Breakpoints

The **display** system makes your UI responsive. It tracks viewport size and exposes
reactive booleans for each breakpoint.

### Breakpoint thresholds

The default thresholds (in pixels, from source) are:

| Breakpoint | Range |
|------------|-------|
| `xs` | `0` – `599` |
| `sm` | `600` – `839` |
| `md` | `840` – `1144` |
| `lg` | `1145` – `1544` |
| `xl` | `1545` – `2137` |
| `xxl` | `2138`+ |

> [!WARNING]
> These thresholds changed in Vuetify 4. If you are migrating from Vuetify 3, the `md`/`lg`
> boundaries are different, so layouts that keyed off the old values may shift. Override
> them via `display.thresholds` if you need the old behavior.

### Using `useDisplay`

```vue
<script setup>
import { useDisplay } from 'vuetify'

const { mobile, name, width, height, mdAndUp, smAndDown, platform } = useDisplay()
</script>

<template>
  <v-navigation-drawer :permanent="mdAndUp" :temporary="smAndDown" />
  <div v-if="mobile">Compact layout</div>
  <div>Current breakpoint: {{ name }} ({{ width }}×{{ height }})</div>
</template>
```

Available reactive members:

- **Exact:** `xs`, `sm`, `md`, `lg`, `xl`, `xxl`
- **And up:** `smAndUp`, `mdAndUp`, `lgAndUp`, `xlAndUp`
- **And down:** `smAndDown`, `mdAndDown`, `lgAndDown`, `xlAndDown`
- **Values:** `name`, `width`, `height`, `mobile`, `mobileBreakpoint`, `thresholds`
- **Platform:** `platform.android`, `platform.ios`, `platform.mac`, `platform.win`,
  `platform.linux`, `platform.chrome`, `platform.firefox`, `platform.touch`, and more.

### The mobile breakpoint

`mobile` is `true` when the viewport is narrower than the **mobile breakpoint**, which
defaults to `'lg'` (1145px). Many components change behavior below it (for example dialogs
become fullscreen). Configure it globally or per component:

```js
createVuetify({
  display: {
    mobileBreakpoint: 'sm',
    thresholds: { sm: 480, md: 768, lg: 1024, xl: 1440, xxl: 1920 },
  },
})
```

```html
<v-data-table :mobile-breakpoint="600" />
```

---

## 7. Icons

Vuetify's icon system is pluggable. A component never hard-codes an SVG path; it asks for an
**icon value** which is resolved through the configured icon **set**.

### Choosing an icon set

The default set is **Material Design Icons (`mdi`)**, using the font version. Fifteen sets
ship in the box: `mdi`, `mdi-svg`, `md`, `fa` (Font Awesome font), `fa-svg`, `fa4`, `fa6`,
`lucide`, `tabler`, `carbon`, `ph` (Phosphor), `ri` (Remix), `bx` (BoxIcons), `ms`, and
`mdi-unocss`.

```js
import { aliases, mdi } from 'vuetify/iconsets/mdi'

createVuetify({
  icons: {
    defaultSet: 'mdi',
    aliases,
    sets: { mdi },
  },
})
```

For the tree-shakeable **SVG** version of Material Design Icons:

```js
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'

createVuetify({
  icons: { defaultSet: 'mdi', aliases, sets: { mdi } },
})
```

### Using icons

The `<v-icon>` component and any `*-icon` prop accept an icon value in several forms:

```html
<!-- From the default set, by name -->
<v-icon icon="mdi-account" />

<!-- A built-in semantic alias (prefixed with $) -->
<v-icon icon="$success" />

<!-- Explicitly from a named set using set:name syntax -->
<v-icon icon="fa:fas fa-home" />

<!-- A raw SVG path string -->
<v-icon icon="svg:M12,2C17.5..." />
```

> [!NOTE]
> Aliases starting with `$` map to Vuetify's **semantic icons** — the icons components use
> internally for states like checkboxes, sorting, navigation, and ratings. Overriding an
> alias (for example `$success`) re-skins every component that uses it. The full alias list
> includes `complete`, `cancel`, `close`, `delete`, `clear`, `success`, `info`, `warning`,
> `error`, `prev`, `next`, `checkboxOn`, `checkboxOff`, `checkboxIndeterminate`, `sortAsc`,
> `sortDesc`, `expand`, `collapse`, `menu`, `dropdown`, `radioOn`, `radioOff`, `edit`,
> `ratingEmpty`, `ratingFull`, `ratingHalf`, `loading`, `first`, `last`, `file`, `plus`,
> `minus`, `calendar`, and more.

### Customizing aliases

```js
import { aliases, mdi } from 'vuetify/iconsets/mdi-svg'
import { mdiHome } from '@mdi/js'

createVuetify({
  icons: {
    defaultSet: 'mdi',
    aliases: { ...aliases, customHome: mdiHome },
    sets: { mdi },
  },
})
```

```html
<v-icon icon="$customHome" />
```

---

## 8. Global Defaults

The **defaults** system lets you set default prop values for any component, globally or for
a scoped subtree. This is how you enforce a consistent look without repeating props on
every element.

### Global defaults

```js
createVuetify({
  defaults: {
    global: {
      ripple: false,            // applies to every component that has a ripple prop
    },
    VBtn: {
      variant: 'flat',
      color: 'primary',
      rounded: 'lg',
    },
    VTextField: {
      variant: 'outlined',
      density: 'comfortable',
    },
  },
})
```

Now every `<v-btn>` is flat and primary-colored unless you override it inline. Resolution
order is: **prop set on the element** → **component default** (`VBtn`) → **global default**
(`global`) → the component's own built-in default.

### Scoped defaults with `<v-defaults-provider>`

To apply defaults to only part of the tree, wrap that part in `<v-defaults-provider>`:

```html
<v-defaults-provider :defaults="{ VBtn: { size: 'small', variant: 'text' } }">
  <v-btn>Small text button</v-btn>
  <v-btn>Another one</v-btn>
</v-defaults-provider>
```

> [!TIP]
> Defaults can also target nested sub-components. A key like `VBtn` inside another
> component's defaults applies only to buttons rendered by that component, which is how you
> theme, for example, the buttons inside a `VCard`.

---

## 9. Blueprints

A **blueprint** is a pre-packaged bundle of `createVuetify` options — themes, defaults,
icons — that gives your whole app a consistent design language in one line. Three Material
Design blueprints ship in the box: `md1`, `md2`, and `md3` (Material Design 1, 2, and 3).

```js
import { createVuetify } from 'vuetify'
import { md3 } from 'vuetify/blueprints/md3'

const vuetify = createVuetify({
  blueprint: md3,
})
```

Your own options are merged on top of the blueprint, so you can adopt the Material 3 look
and still override individual colors or defaults:

```js
const vuetify = createVuetify({
  blueprint: md3,
  theme: {
    themes: { light: { colors: { primary: '#6750A4' } } },
  },
})
```

---

## 10. Internationalization & RTL

Vuetify components display some text of their own (pagination labels, data-table messages,
"no data" strings, etc.). The **locale** system controls that text and supports
right-to-left layouts.

### Built-in languages

Translations ship for **43 languages**, including English (`en`, the fallback), German
(`de`), Spanish (`es`), French (`fr`), Chinese (`zh-Hans` / `zh-Hant`), Japanese (`ja`),
Korean (`ko`), Arabic (`ar`), Hebrew (`he`), Persian (`fa`), Russian (`ru`), Portuguese
(`pt`), Italian (`it`), and many more.

```js
import { createVuetify } from 'vuetify'
import { en, de, es } from 'vuetify/locale'

const vuetify = createVuetify({
  locale: {
    locale: 'de',
    fallback: 'en',
    messages: { en, de, es },
  },
})
```

You can also set the decimal and grouping separators used by number formatting:

```js
createVuetify({
  locale: { decimalSeparator: ',', numericGroupSeparator: '.' },
})
```

### Switching locale at runtime

```vue
<script setup>
import { useLocale } from 'vuetify'

const { current } = useLocale()
function setGerman () { current.value = 'de' }
</script>
```

### Integrating with vue-i18n

If your app already uses **vue-i18n**, plug it into Vuetify with the supplied adapter so
both share one source of translations:

```js
import { createI18n, useI18n } from 'vue-i18n'
import { createVueI18nAdapter } from 'vuetify/locale/adapters/vue-i18n'
import { en, de } from 'vuetify/locale'

const i18n = createI18n({
  legacy: false,
  locale: 'en',
  messages: { en: { $vuetify: en }, de: { $vuetify: de } },
})

const vuetify = createVuetify({
  locale: {
    adapter: createVueI18nAdapter({ i18n, useI18n }),
  },
})
```

### Right-to-left (RTL)

The languages `ar` (Arabic), `fa` (Persian), and `he` (Hebrew) are RTL by default. Enable
RTL globally or scope it to part of the page with `<v-locale-provider>`:

```html
<v-locale-provider rtl>
  <!-- this subtree renders right-to-left -->
</v-locale-provider>
```

Use `useRtl()` to read or react to the current direction:

```vue
<script setup>
import { useRtl } from 'vuetify'
const { isRtl } = useRtl()
</script>
```

---

## 11. Dates

The date-based components — `<v-date-picker>`, `<v-date-input>`, `<v-calendar>` — work
through a **date adapter** so you can use whichever date library your project already
depends on. The built-in `VuetifyDateAdapter` uses the native `Intl` API and needs no extra
dependency.

```js
import { createVuetify } from 'vuetify'

// Uses the built-in adapter — nothing else required
const vuetify = createVuetify()
```

To use `date-fns`, `luxon`, `dayjs`, or `moment`, install the matching `@date-io` adapter
and pass it:

```js
import { createVuetify } from 'vuetify'
import DateFnsAdapter from '@date-io/date-fns'
import enUS from 'date-fns/locale/en-US'

const vuetify = createVuetify({
  date: {
    adapter: DateFnsAdapter,
    locale: { en: enUS },
  },
})
```

> [!NOTE]
> Vuetify maps its locale codes to standard locale strings for dates automatically (for
> example `en` → `en-US`, `de` → `de-DE`, `ja` → `ja-JP`), so date formatting follows the
> active language out of the box.

---

## 12. The Component Catalog

Vuetify ships **104 stable components** plus a set of experimental **labs** components.
Every component is registered globally by `createVuetify`, so you can use them in any
template without importing them (with the Vite plugin handling tree-shaking). Components are
written in PascalCase (`VTextField`) and used in kebab-case in templates (`<v-text-field>`).

> [!IMPORTANT]
> Each component exposes a large, strongly-typed set of props, slots, and events. The
> exhaustive, always-current per-prop API reference is generated directly from the source
> types and published at **[vuetifyjs.com](https://vuetifyjs.com)**. This guide groups the
> components by purpose so you can find the right one; consult the online API for the full
> prop signature of any individual component.

### Layout & Application

| Component | Purpose |
|-----------|---------|
| `v-app` | Required root wrapper. |
| `v-main` | Main content region that flexes around bars/drawers. |
| `v-app-bar` | Top/bottom application toolbar. |
| `v-system-bar` | Slim status bar. |
| `v-toolbar` | Generic toolbar (used standalone or inside bars). |
| `v-navigation-drawer` | Side navigation panel. |
| `v-footer` | Page footer. |
| `v-layout` / `v-layout-item` | Low-level layout primitives. |

### Grid & Layout

| Component | Purpose |
|-----------|---------|
| `v-container` | Centered, responsive content wrapper. |
| `v-row` / `v-col` | 12-column responsive flexbox grid. |
| `v-spacer` | Flexible space inside flex containers. |
| `v-responsive` | Enforces an aspect ratio / responsive sizing. |
| `v-sheet` | A themed surface — the base for cards and panels. |
| `v-divider` | Horizontal or vertical separating line. |

### Buttons & Actions

| Component | Purpose |
|-----------|---------|
| `v-btn` | Button (text, outlined, flat, icon, block, loading…). |
| `v-btn-group` / `v-btn-toggle` | Grouped and toggle-selectable buttons. |
| `v-icon-btn` | Icon-only button variant. |
| `v-fab` | Floating action button. |
| `v-speed-dial` | FAB that expands to reveal more actions. |
| `v-icon` | Render an icon from any configured set. |

### Form Inputs & Controls

| Component | Purpose |
|-----------|---------|
| `v-text-field` | Single-line text input. |
| `v-textarea` | Multi-line text input. |
| `v-select` | Dropdown selection. |
| `v-autocomplete` | Select with type-ahead filtering. |
| `v-combobox` | Autocomplete that also accepts free input. |
| `v-checkbox` / `v-radio` / `v-radio-group` | Selection controls. |
| `v-switch` | On/off toggle. |
| `v-slider` / `v-range-slider` | Single and dual-handle sliders. |
| `v-file-input` / `v-file-upload` | File selection and upload. |
| `v-otp-input` | One-time-password entry. |
| `v-number-input` | Numeric input with steppers. |
| `v-color-input` / `v-color-picker` | Color selection. |
| `v-date-input` / `v-date-picker` | Date selection. |
| `v-time-picker` | Time selection. |
| `v-rating` | Star/icon rating input. |
| `v-form` | Form wrapper with validation orchestration. |
| `v-input` / `v-field` / `v-label` / `v-messages` / `v-counter` | Building blocks shared by the inputs above. |
| `v-selection-control` / `v-selection-control-group` | Low-level primitives for checkbox/radio/switch. |
| `v-confirm-edit` | Inline edit-with-confirm wrapper. |
| `v-validation` | Standalone validation wrapper. |

### Data Presentation

| Component | Purpose |
|-----------|---------|
| `v-data-table` | Sortable, paginated, selectable data table (with server-side and virtual variants). |
| `v-data-iterator` | Headless iteration over data with the same sorting/paging logic. |
| `v-table` | Plain styled HTML table. |
| `v-list` | Vertical list with items, groups, subheaders, dividers. |
| `v-virtual-scroll` | Renders only visible rows for huge lists. |
| `v-treeview` | Hierarchical tree with selection (labs/stable). |
| `v-timeline` | Vertical/horizontal event timeline. |
| `v-sparkline` | Inline mini line/bar chart. |
| `v-infinite-scroll` | Load more content as the user scrolls. |
| `v-pagination` | Page navigation control. |

### Containers & Surfaces

| Component | Purpose |
|-----------|---------|
| `v-card` | Material card with title, text, actions. |
| `v-expansion-panel` | Accordion-style collapsible panels. |
| `v-banner` | Prominent message banner. |
| `v-alert` | Contextual alert/notification box. |
| `v-chip` / `v-chip-group` | Compact tags / filter chips. |
| `v-avatar` | Circular image/initials container. |
| `v-badge` | Small status indicator overlaid on a child. |
| `v-empty-state` | Friendly placeholder for empty content. |
| `v-kbd` / `v-code` | Keyboard-key and inline-code styling. |

### Navigation & Disclosure

| Component | Purpose |
|-----------|---------|
| `v-tabs` | Tabbed navigation. |
| `v-breadcrumbs` | Breadcrumb trail. |
| `v-bottom-navigation` | Mobile bottom navigation bar. |
| `v-stepper` / `v-stepper-vertical` | Multi-step wizard. |
| `v-window` | Swipeable/animated view container. |
| `v-carousel` | Image/content carousel. |
| `v-menu` | Anchored popup menu. |
| `v-dialog` | Modal dialog. |
| `v-bottom-sheet` | Sheet that slides up from the bottom. |
| `v-overlay` | Low-level scrim/positioning primitive behind menus and dialogs. |
| `v-tooltip` | Hover/focus tooltip. |
| `v-snackbar` / `v-snackbar-queue` | Transient toast notifications (single and queued). |

### Feedback & Progress

| Component | Purpose |
|-----------|---------|
| `v-progress-linear` | Linear progress / loading bar. |
| `v-progress-circular` | Circular progress spinner. |
| `v-skeleton-loader` | Placeholder shimmer while content loads. |
| `v-pull-to-refresh` | Pull-down-to-refresh gesture wrapper. |

### Media & Utility

| Component | Purpose |
|-----------|---------|
| `v-img` | Responsive image with lazy-loading and placeholders. |
| `v-parallax` | Parallax-scrolling image. |
| `v-hover` | Exposes hover state to its slot. |
| `v-lazy` | Defers rendering until the element scrolls into view. |
| `v-no-ssr` | Renders children only on the client. |
| `v-hotkey` | Displays and binds keyboard shortcuts. |
| `v-item-group` | Generic selectable group logic. |
| `v-slide-group` | Horizontally scrollable group of items. |

### Providers (configuration components)

| Component | Purpose |
|-----------|---------|
| `v-theme-provider` | Apply a theme to a subtree. |
| `v-locale-provider` | Apply a locale / RTL to a subtree. |
| `v-defaults-provider` | Apply prop defaults to a subtree. |

### Labs (experimental)

The `labs` entry contains newer components whose API may still change: `VAvatarGroup`,
`VCommandPalette`, `VDateRangePicker`, `VHeatmap`, `VHighlight`, `VMaskInput`,
`VMonthPicker`, `VPie`, `VProgress`, and `VVideo`. Opt in explicitly:

```js
import { createVuetify } from 'vuetify'
import { VTreeview } from 'vuetify/labs/VTreeview'

createVuetify({
  components: { VTreeview },
})
```

> [!WARNING]
> Labs components are production-usable but **not API-stable**. Pin your Vuetify version and
> review the changelog before upgrading if you depend on a labs component.

### Example: a small but real form

```vue
<template>
  <v-card class="mx-auto pa-6" max-width="420">
    <v-card-title>Sign up</v-card-title>
    <v-form @submit.prevent="onSubmit">
      <v-text-field
        v-model="email"
        label="Email"
        :rules="[v => !!v || 'Required', v => /.+@.+/.test(v) || 'Invalid email']"
        prepend-inner-icon="$info"
      />
      <v-text-field v-model="password" label="Password" type="password" />
      <v-btn type="submit" color="primary" block class="mt-2">Create account</v-btn>
    </v-form>
  </v-card>
</template>

<script setup>
import { ref } from 'vue'
const email = ref('')
const password = ref('')
function onSubmit (e) { /* e is a SubmitEventPromise — see Forms section */ }
</script>
```

---

## 13. Forms & Validation

`<v-form>` coordinates validation across the inputs it contains. Each input registers
itself with the form; the form aggregates their validity into a single reactive state.

### Per-field rules

Every input accepts a `:rules` array. Each rule is a function returning `true` when valid or
a **string error message** when invalid:

```html
<v-text-field
  v-model="username"
  label="Username"
  :rules="[
    v => !!v || 'Username is required',
    v => v.length >= 3 || 'Must be at least 3 characters',
  ]"
/>
```

### Form-level validation

```vue
<script setup>
import { ref } from 'vue'

const form = ref(null)

async function submit () {
  const { valid } = await form.value.validate()
  if (valid) {
    // all fields passed — proceed
  }
}

function clear () {
  form.value.reset()           // clear values and validation
  form.value.resetValidation() // clear only validation messages
}
</script>

<template>
  <v-form ref="form">
    <!-- inputs -->
    <v-btn @click="submit">Submit</v-btn>
    <v-btn @click="clear">Reset</v-btn>
  </v-form>
</template>
```

### When validation runs

The `validate-on` prop controls timing. The default is **`input`** (validate as the user
types). Other values let you validate on `blur`, on `submit`, or combinations such as
`blur lazy`.

```html
<v-form validate-on="submit">…</v-form>
```

### Submitting

`<v-form>`'s `@submit` event provides a **`SubmitEventPromise`** — a native submit event
that is also a promise resolving to `{ valid, errors }`:

```html
<v-form @submit.prevent="(e) => e.then(({ valid }) => valid && save())">
```

| Prop / option | Effect |
|---------------|--------|
| `validate-on` | When fields validate (`input` default, `blur`, `submit`, `lazy`…). |
| `fast-fail` | Stop validating at the first failing field. |
| `disabled` | Disable every input in the form. |
| `readonly` | Make every input read-only. |

> [!TIP]
> Use `fast-fail` on large forms where you only need to know *whether* the form is valid,
> not collect every error at once — it stops at the first failure.

---

## 14. Directives

Directives add low-level DOM behavior to any element, not just Vuetify components. Register
them globally (`createVuetify({ directives })`) or individually. Eight directives ship:

| Directive | Usage | Purpose |
|-----------|-------|---------|
| `v-ripple` | `v-ripple` | Material "ink" ripple on click/touch. |
| `v-resize` | `v-resize="onResize"` | Call a handler when the window resizes. |
| `v-intersect` | `v-intersect="onIntersect"` | Fire when the element enters/leaves the viewport (IntersectionObserver). |
| `v-mutate` | `v-mutate="onMutate"` | Fire when the element's DOM changes (MutationObserver). |
| `v-scroll` | `v-scroll="onScroll"` | Call a handler on scroll. |
| `v-touch` | `v-touch="{ left, right, up, down }"` | Detect swipe gestures. |
| `v-click-outside` | `v-click-outside="onOutside"` | Fire when a click lands outside the element. |
| `v-tooltip` | `v-tooltip="'Help text'"` | Attach a tooltip directly to an element. |

```html
<div v-ripple class="pa-4">Click me for a ripple</div>

<div v-intersect="(isIntersecting) => visible = isIntersecting">
  Lazy-loaded section
</div>

<v-card v-touch="{ left: next, right: prev }">Swipe me</v-card>
```

> [!NOTE]
> Many components use these directives internally — `<v-btn>`, for example, applies
> `v-ripple` automatically (toggle it with the `ripple` prop). You only need to register a
> directive yourself when applying it to your own elements.

---

## 15. Programmatic Scrolling

The `useGoTo()` composable performs smooth, animated scrolling to a target — an element,
a CSS selector, a component ref, or a pixel offset.

```vue
<script setup>
import { useGoTo } from 'vuetify'

const goTo = useGoTo()

function scrollToFaq () {
  goTo('#faq')                          // to an element by selector
}

function scrollToTop () {
  goTo(0)                               // to a pixel offset
}

function scrollSidewaysTo () {
  goTo.horizontal('#col-5')             // horizontal scrolling
}
</script>
```

Configure duration, easing, offset, and container globally or per call:

```js
createVuetify({
  goTo: {
    duration: 300,           // ms (default)
    easing: 'easeInOutCubic', // default easing pattern
    offset: 0,
  },
})
```

```js
goTo('#section', { duration: 600, offset: -64 }) // offset accounts for a fixed app bar
```

> [!NOTE]
> `useGoTo` automatically falls back to an instant jump when the user prefers reduced
> motion, and it respects RTL for horizontal scrolling.

---

## 16. Styling, Utility Classes & SASS

### Utility classes

Vuetify generates utility classes for theme colors and common layout needs:

- **Color:** `bg-primary`, `text-secondary`, `border-error` (one set per theme color).
- **Spacing:** `pa-4` (padding all), `ma-2` (margin all), `mt-3`, `px-6`, etc., on a
  4px scale.
- **Display & elevation:** responsive display helpers and `elevation-0` … `elevation-24`.
- **Screen-reader and pointer-event** helpers.

```html
<v-sheet class="bg-primary text-white pa-6 rounded-lg elevation-4">
  Themed, padded, elevated surface
</v-sheet>
```

### Importing precompiled CSS

The simplest option imports the precompiled stylesheet:

```js
import 'vuetify/styles'
```

### Customizing with SASS variables

To override Vuetify's SASS variables (colors, spacing scale, component variables), configure
the Vite or Webpack plugin to point at your own SASS entry, then import the settings:

```scss
// src/styles/settings.scss
@use 'vuetify/settings' with (
  $button-height: 44px,
  $border-radius-root: 6px,
);
```

The framework exposes three SASS entry points:

| Entry | Contents |
|-------|----------|
| `vuetify` | Global CSS (reset, utilities), no component styles. |
| `vuetify/settings` | All SASS variables, including per-component variables. |
| `vuetify/tools` | Mixins and functions. |

> [!TIP]
> Editing SASS variables requires the build plugin (`vite-plugin-vuetify` or
> `webpack-plugin-vuetify`) with its `styles.configFile` option set — the precompiled
> `vuetify/styles` import cannot be customized after the fact.

---

## 17. Tree-Shaking & Production Builds

Importing every component is fine for prototypes but bloats production bundles. The official
build plugins import only the components you actually use, automatically.

### Vite plugin

```ts
import vuetify from 'vite-plugin-vuetify'

export default defineConfig({
  plugins: [
    vuetify({ autoImport: true }), // auto-imports only used components + directives
  ],
})
```

With `autoImport: true` you simply write `<v-btn>` in a template and the plugin adds the
matching import behind the scenes — no manual `import` and no full-library bundle.

### Manual per-component imports

Without the plugin, import components from their grouped path:

```js
import { VBtn } from 'vuetify/components/VBtn'
import { VList, VListItem } from 'vuetify/components/VList'
```

> [!NOTE]
> Components are grouped by their top-level name. `VListItem`, `VListGroup`, and
> `VListItemTitle` all live under `vuetify/components/VList`. Directives import from
> `vuetify/directives/<name>`.

---

## 18. Server-Side Rendering (SSR)

Vue 3 cannot auto-detect SSR, so frameworks like Nuxt and Gridsome must tell Vuetify
explicitly by setting `ssr: true`:

```js
import '@mdi/font/css/materialdesignicons.css'
import 'vuetify/styles'
import { createVuetify } from 'vuetify'

const vuetify = createVuetify({
  ssr: true,
})
```

You may pass an object to seed the display dimensions used during the server render:

```js
createVuetify({
  ssr: { clientWidth: 1280, clientHeight: 800 },
})
```

> [!IMPORTANT]
> When `ssr` is enabled, Vuetify defers its first display update until after hydration to
> avoid a hydration mismatch between the server-rendered and client-rendered markup. If you
> see hydration warnings, confirm `ssr: true` is set.

---

## 19. Troubleshooting

The issues below are drawn from the framework's own issue tracker and the behaviors visible
in source. Each lists the symptom, the cause, and what to do.

### Error: `Could not find Vuetify theme injection`

- **Cause:** `useTheme()` (or another `use*` composable) was called outside a component's
  `setup()`, or the component is not a descendant of an app that registered the
  `createVuetify` plugin.
- **Solution:** Call the composable inside `<script setup>` / `setup()`, and ensure
  `app.use(vuetify)` ran and your UI is wrapped in `<v-app>`.
- **Prevention:** Never call `useTheme`/`useDisplay`/`useLocale` from plain module scope.

### Error: `Could not find aliased icon "$xyz"`

- **Cause:** An icon value used a `$alias` that is not defined in your `icons.aliases`.
- **Solution:** Add the alias to your `icons.aliases`, or import the set's default
  `aliases` and spread them: `aliases: { ...aliases, xyz: mdiSomething }`.
- **Prevention:** Always pass the set's `aliases` export to `createVuetify`.

### Theme `toggle()` behaves inconsistently after enabling theme transitions

- **Cause:** With animated transitions enabled, a transition origin set by a previous call
  can carry over (tracked upstream for `ThemeInstance.toggle()`).
- **Solution:** Call `theme.setTransitionOrigin(event)` immediately before the toggle, or
  toggle without a transition (`theme.toggle(undefined, false)`) when you do not need the
  animation.

### `VBtn` `size` as a number does not change the font size

- **Cause:** Numeric `size` controls dimensions but not typography in the current version.
- **Solution:** Use a named size (`x-small`, `small`, `default`, `large`, `x-large`) or add
  a text utility class (`text-h6`) for font scaling.

### `VSelect` with `multiple` and duplicate items cannot deselect an option

- **Cause:** Duplicate item values make selection ambiguous.
- **Solution:** Ensure each item has a unique value via `item-value`, or de-duplicate the
  items array before binding it.

### `VDialog` with a percentage `max-width` is not respected

- **Cause:** Percentage widths on the dialog were affected by a layout change.
- **Solution:** Use an explicit pixel/`rem` `max-width`, or wrap the dialog content in a
  sized container.

### MDI icons do not render in an offline PWA

- **Cause:** The Material Design Icons **font** files were not cached by the service
  worker, so glyphs cannot load offline.
- **Solution:** Ensure your PWA precaches the `@mdi/font` files, or switch to the
  tree-shakeable SVG set (`vuetify/iconsets/mdi-svg`) so icon paths are bundled into JS.

### Icons / styles don't appear at all

- **Cause:** Missing stylesheet or font import.
- **Solution:** Confirm you imported `'vuetify/styles'` and an icon font/CSS (for example
  `'@mdi/font/css/materialdesignicons.css'`), and that the app is inside `<v-app>`.

> [!TIP]
> For a question that isn't covered here, the Vuetify community Discord and the issue
> generator at `issues.vuetifyjs.com` are the official support channels.

---

## 20. Frequently Asked Questions

**Q: Which Vue version does Vuetify 4 require?**
Vue **3.5.0 or later**. Vuetify 4 does not support Vue 2.

**Q: Do I have to import each component?**
No. With `create-vuetify` or the Vite plugin's `autoImport`, components are registered and
tree-shaken automatically. Manual imports are only needed if you are not using the plugin.

**Q: Why do I need `<v-app>`?**
It establishes the layout root and hosts theming and overlay providers. Components like
menus, dialogs, app bars, and drawers rely on it to position correctly.

**Q: How do I switch between light and dark mode?**
Call `useTheme().toggle()`, or set `theme.defaultTheme` to `'system'` to follow the OS.

**Q: Does Vuetify follow the operating system's dark mode automatically?**
Yes. The default theme is `'system'`, which tracks `prefers-color-scheme` and updates live.

**Q: How do I change the default look of all buttons (or any component)?**
Use the `defaults` option in `createVuetify`, keyed by the component name (e.g. `VBtn`), or
wrap a subtree in `<v-defaults-provider>`.

**Q: Can I use a font icon library other than Material Design Icons?**
Yes. Choose from 15 built-in sets (Font Awesome, Lucide, Tabler, Phosphor, Remix, Carbon,
BoxIcons, Material Symbols, and more) via `icons.defaultSet`, or mix sets using the
`set:name` prefix.

**Q: How do I make my app responsive?**
Use `useDisplay()` for reactive breakpoint booleans (`mobile`, `mdAndUp`, etc.) and the
12-column grid (`<v-row>` / `<v-col>`) with responsive props.

**Q: Which languages are supported out of the box?**
43, with English as the fallback. You can also wire Vuetify into an existing vue-i18n setup.

**Q: How do I support right-to-left languages?**
Arabic, Persian, and Hebrew are RTL by default. Use `<v-locale-provider rtl>` or
`useRtl()` to control direction.

**Q: My date picker needs a specific date library — is that possible?**
Yes. The built-in adapter uses native `Intl`; for `date-fns`, `luxon`, `dayjs`, or
`moment`, pass the matching `@date-io` adapter to the `date` option.

**Q: Are the "labs" components safe to use?**
They work, but their API is not stable. Pin your Vuetify version and check the changelog
before upgrading.

**Q: How do I customize SASS variables?**
Configure the Vite/Webpack plugin's `styles.configFile` and `@use 'vuetify/settings'` with
your overrides. The precompiled `vuetify/styles` import cannot be customized.

**Q: How do I reduce my production bundle size?**
Use the Vite plugin with `autoImport: true`, the SVG icon set, and import only the locales
you ship.

---

## 21. Reference

### `createVuetify` options at a glance

| Option | Purpose |
|--------|---------|
| `theme` | Light/dark/custom palettes, default theme, transitions, variations. |
| `display` | Breakpoint thresholds and the mobile breakpoint. |
| `icons` | Default icon set, sets, and `$` aliases. |
| `locale` | Translations, fallback, RTL, separators, i18n adapter. |
| `date` | Date adapter and locale map for date components. |
| `defaults` | Global and per-component default prop values. |
| `goTo` | Default scroll duration, easing, offset, container. |
| `blueprint` | A preset bundle (`md1`/`md2`/`md3`) merged under your options. |
| `components` / `directives` / `aliases` | Explicit registration of components, directives, and component aliases. |
| `ssr` | Enable server-side rendering support. |

### Breakpoint thresholds (px)

| `xs` | `sm` | `md` | `lg` | `xl` | `xxl` |
|------|------|------|------|------|-------|
| 0 | 600 | 840 | 1145 | 1545 | 2138 |

### Default theme colors

| Token | Light | Dark |
|-------|-------|------|
| `primary` | `#1867C0` | `#2196F3` |
| `secondary` | `#48A9A6` | `#54B6B2` |
| `background` | `#FFFFFF` | `#121212` |
| `surface` | `#FFFFFF` | `#212121` |
| `success` | `#4CAF50` | `#4CAF50` |
| `info` | `#2196F3` | `#2196F3` |
| `warning` | `#FB8C00` | `#FB8C00` |
| `error` | `#B00020` | `#CF6679` |

### Composables

| Composable | Returns |
|------------|---------|
| `useTheme()` | Theme instance: `name`, `current`, `change`, `toggle`, `cycle`. |
| `useDisplay()` | Breakpoint booleans, `mobile`, `width`/`height`, `platform`. |
| `useLocale()` | Current locale, translation function. |
| `useRtl()` | `isRtl`, `rtlClasses`. |
| `useGoTo()` | Smooth-scroll function (with `.horizontal`). |
| `useDefaults()` | Resolved props merged with global/scoped defaults. |

### Key exports

| Path | Contents |
|------|----------|
| `vuetify` | `createVuetify`, public composables. |
| `vuetify/styles` | Precompiled global CSS. |
| `vuetify/components` / `vuetify/components/<Name>` | All / grouped components. |
| `vuetify/directives` / `vuetify/directives/<name>` | All / individual directives. |
| `vuetify/blueprints/<name>` | `md1`, `md2`, `md3` blueprints. |
| `vuetify/locale` / `vuetify/locale/adapters/<name>` | Translations / i18n adapters. |
| `vuetify/iconsets/<name>` | Icon set presets. |

### Fonts via `unplugin-fonts` (recommended config)

```ts
import { defineConfig } from 'vite'
import ViteFonts from 'unplugin-fonts/vite'

export default defineConfig({
  plugins: [
    ViteFonts({
      fontsource: {
        families: [
          { name: 'Roboto', weights: [100, 300, 400, 500, 700, 900], styles: ['normal', 'italic'] },
        ],
      },
    }),
  ],
})
```

```ts
// main.ts
import 'unfonts.css'
```

---

_Generated June 2026 from vuetifyjs/vuetify at bbffe05. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
