File: README.md
๐ฅ๏ธ Documentation
To check out the documentation, visit vuetifyjs.com.
โก Quick Start
Getting started with Vuetify is easy. To create a new project, choose your package manager and run one of the following commands:
Using pnpm
pnpm create vuetifyUsing yarn
yarn create vuetifyUsing npm
npm create vuetify@latestUsing bun
bun create vuetifyFor more information on how to get started, such as using Nuxt or Laravel, check out the official Installation guide.
๐ Supporting Vuetify
Vuetify is a MIT licensed project that is developed and maintained by the Core Team. Sponsor Vuetify and receive some awesome perks and support Open Source Software at the same time! ๐
What's the difference between GitHub Sponsors and OpenCollective?
Funds donated through GitHub Sponsors directly support John Leider and the ongoing development and maintenance of Vuetify. Funds donated via Open Collective are managed with transparent expenses and will be used for compensating work and expenses for Core team members. Your name/logo will receive proper recognition and exposure by donating on either platform.
**Special Sponsor**
**Diamond Sponsors**
**Platinum Sponsors**
๐ Introduction
Vuetify is a no design skills required UI Library with beautifully handcrafted Vue Components. No design skills required โ everything you need to create amazing applications is at your fingertips. Vuetify has a massive API that supports any use-case. Some highlights include:
- Customizable: Extensive customization options with SASS/SCSS and Default configuration and Blueprints
- Responsive Layout: The default configuration of Vuetify components is responsive, allowing your application to adapt to different screen sizes.
- Theme System: A powerful color system that makes it easy to style your application with a consistent color palette.
- Vite Support: Smaller bundle sizes with automatic tree-shaking
- min. 6 months Long-term support for Major releases
- Internationalization: 42+ supported languages
Browser Support
Vuetify supports all modern browsers, including Safari 13+ (using polyfills). Components are designed for a minimum width of 320px.
๐ Vuetify Ecosystem
Resources
| Name | Description |
|---|---|
| ๐ถ๏ธ Vuetify Awesome | Awesome stuff built with Vuetify. |
| ๐๏ธ Vuetify Bin | A pastebin for saving code snippets. |
| ๐ซง Vuetify Create | Scaffolding tools for creating new Vuetify projects. |
| ๐ญ Vuetify Discord | Our massive and inclusive Discord server where you can ask questions, share feedback, and connect with other Vuetify developers. |
| ๐งน Vuetify ESLint | An opinionated ESLint config for styling and an ESLint plugin for upgrading Vuetify version. |
| ๐ Vuetify Issues | A web application for reporting bugs and issues with Vuetify, Documentation, or one of our other packages. |
| ๐ฆ Vuetify Loader | A monorepo of compiler plugins for autoloading Vuetify components and configuring styles. |
| ๐ง Vuetify MCP | A Model Context Protocol server for developing with Vuetify and Agents. |
| ๐ฎ Vuetify Playground | A Vuetify 3 playground built using vuejs/repl where you can play with our components. |
| โ๏ธ Vuetify Snips | Pre-built code snippets for Vuetify components that you can use in your projects |
| ๐ Vuetify Store | The official Vuetify Store where you can download free digital products, purchase pre-made themes, and more. |
๐โโ๏ธ Questions
For help and support questions, please use our Discord community. This issue list of this repo is exclusively for bug reports and feature requests.
๐ Issues
Use our Issue generator to report bugs and request new features.
Please make sure to read the Important Information before opening an issue. Issues not confirming to the guidelines may be closed immediately.
2๏ธโฃ Vuetify 2 Support
Vuetify 2 is now End Of Life (EOL) and is no longer supported, even for security issues. Commercial support for this version is available from our partner, HeroDevs.
๐ Changelog
Detailed changes for each release are documented in the release notes.
๐โโ๏ธ Contributing
Developers interested in contributing should read the Code of Conduct and the Contribution Guide.
Please do not ask general questions in an issue. Issues are only to report bugs, suggest
enhancements, or request new features. For general questions and discussions, ask in the community chat.
To help you get you familiar with our contribution process, we have a list of good first issues that contain bugs which have a relatively limited scope. This is a great place to get started. If you have any questions, please join us on the community chat.
We also have a list of help wanted issues that you might want to check.
๐ License
Vuetify is available under the MIT software license.
Copyright (c) 2016-present Vuetify, LLC
This project exists thanks to all the people who contribute ๐!
File: packages/docs/src/pages/en/getting-started/browser-support.md
meta:
title: Browser support
keywords: vuetify browser support
related:
- /getting-started/installation/
- /introduction/why-vuetify/
- /features/sass-variables/
Browser support
Vuetify 4 is a next generation framework that takes advantage of the latest web technology features and requires an evergreen browser to function.
Browsers
This is not an exhaustive list of compatible browsers, but the main targeted ones. If you are using a browser that is not listed here, it is not officially supported.
| Browser | Version | Status |
|---|---|---|
| Chromium (Chrome, Edge) | 119 | โ Supported * |
| ^^ | 99 | โ ๏ธ Partial support ** |
| Firefox | 128 | โ Supported * |
| ^^ | 97 | โ ๏ธ Partial support ** |
| Safari | 16.4 | โ Supported |
| Internet Explorer | โ Not supported | |
| Other Browsers | โ Not officially supported |
- All browsers on iOS use WebKit and have the same support as Safari
** Some components may have incorrect colors due to lack of support forrelative color syntax (e.g.rgb(from ...) ). VNumberInput locale-aware grouping requiresIntl.NumberFormat with stringuseGrouping options (Chrome 106+, Firefox 115+).
This table is updated with minor releases of Vuetify. Chrome, Firefox, and Safari will be supported at least two years back from the Vuetify x.x.0 release date.
Current start date is December 2023.
Support for older browsers may be possible with additional polyfills and PostCSS plugins, but has not been tested and is not guaranteed. If you need to support older browsers we recommend using Vuetify 2 or 3.
File: packages/docs/src/pages/en/getting-started/contributing.md
meta:
title: Contributing
keywords: contribute, contributing, feature request
related:
- /getting-started/unit-testing/
- /about/code-of-conduct/
- /introduction/roadmap/
Contributing
Vuetify is made possible by an amazing community that submits issues, creates pull requests, and provides invaluable feedback.
It is our job to enable you to create amazing applications. A lot of the time, you come across something that can be made better. Maybe you find a bug, or you have an idea for additional functionality. That's great! It's as easy as cloning the Vuetify repository to get started working in a development environment.
Reporting Issues
The issue list of this repo is exclusively for bug reports and feature requests. Non-conforming issues will be closed immediately. Before reporting an issue:
- Search for similar issues, it may have been answered already.
If a similar issue already exists, you do not need to open another issue for this, if you want to help with it in any way, you can help by giving appropriate information in the already existing issue.
- Try to reproduce with the latest version in Vuetify Play or a repository that can be cloned to produce the expected behavior.
- Make sure that the reproduction is MINIMAL and CONCISE
These steps ensure that we have all the information necessary to quickly triage and resolve your issue. Once your reproduction is complete, submit a new issue using the Vuetify Issue Creator. Using this issue creator is required, otherwise the issue will be closed automatically.
When writing an issue please provide as much detail as possible. Note that "reproduction steps" should be a series of actions another developer should take after clicking your reproduction link, not a recollection of how you discovered the bug.
Issues that are convoluted and lacking a proper reproduction may be closed by a member of the Core Team. For additional questions regarding reporting issues and creating reproductions, join the official Vuetify Discord community.
::: tip
When you create a reproduction, exclude all elements, properties, and data variables that are not needed for the reproduction. This helps drastically reduce the time it takes to triage the issue and ultimately resolve it.
:::
In the next section you will learn step-by-step how to set up your local environment and how to configure Vuetify for development.
Local development
The Vuetify repository is a lerna monorepo that connects the vuetify library, docs, api generator, and reduces the friction of working with multiple projects at once. The following guide is designed to get you up and running in no time.
Setting up your environment
We recommend using FNM (with all four options enabled) to automatically set up and use the exect node and pnpm versions specified in package.json.
Required software:
Some of our dependencies use node-gyp to build themselves. You don't need to install node-gyp itself but may require additional tools, especially on windows. See the node-gyp documentation for more details.
Once you have everything installed, clone the repository:
# Using HTTPS
git clone https://github.com/vuetifyjs/vuetify.git
# Using SSH
git clone [email protected]:vuetifyjs/vuetify.git::: info
Which remote URL should I use?
:::
Then install dependencies and perform an initial build to link all the packages together:
# Navigate to the vuetify folder
cd vuetify
# Install all project dependencies
pnpm i
# Build the packages
pnpm build vuetify
pnpm build apiThe build process compiles all the Vuetify packages for development and may take a while (grab some โ). Once the packages are built, you can start developing.
Vuetify
The Vuetify library is located in packages/vuetify. In packages/vuetify/dev you will find a Playground.vue file; running pnpm dev from the project root will start a dev server on localhost:8090 with this file loaded. Test your changes in the Playground.vue file you copied, then paste its contents into your pull request when you're ready.
You can also test Vuetify in your own project using pnpm link:
- Navigate to
packages/vuetify - Run
pnpm link --global - Navigate to your project's directory
- Run
pnpm link --global vuetify - Clear Vite's cache by deleting
node_modules/.vitefolder
If your project is using vuetify-loader you will have to run pnpm build:lib in the vuetify package to see changes, otherwise you can use pnpm watch for incremental builds.
Playground.vue
The Playground file is a cleanroom used for Vuetify development and is the recommended way to iterate on changes within the framework.
<template>
<v-app>
<v-container>
</v-container>
</v-app>
</template>
<script setup>
//
</script>Automated testing
Vuetify uses Vitest for unit tests, Vitest browser mode with Playwright for component interaction tests, and Vizzly for visual regression tests.
pnpm test- run all testspnpm test:unit- run only unit testspnpm test:browser- run only browser testspnpm test:open- run browser tests in a chrome window- use this if you need devtools to debug a failing test
pnpm test:screen- run only screenshot tests, saves a report to http://localhost:47392/pnpm tdd- start the vizzly dev server, follow withtest,test:screen,test:browser, ortest:opento actually run tests. Screenshot baselines and diffs can be managed and viewed at http://localhost:47392/- run
pnpm tdd:stopwhen you're done to kill the background process
- run
The test:* commands all accept a list of test names to filter by, eg. pnpm test textfield textarea to only run VTextField and VTextarea tests.
Visual regression workflow
- Checkout the base branch (
masterordev) - Run
pnpm tdd - Visit http://localhost:47392/stats and click "Reset baselines"
- Run
pnpm test:screen - Click "Accept all changes"
- Checkout your PR branch
- Run
pnpm test:screenagain - Any visual differences will be shown on http://localhost:47392
Documentation
The documentation is located in packages/docs but also uses some files from packages/api-generator. A dev server for the documentation can be started by running pnpm dev docs from the project root and will be available on localhost:8095 by default.
If you want to see changes from Vuetify in the documentation you need to run pnpm build:lib in the vuetify package before starting the documentation server.
API Generator
All api descriptions are managed via the api-generator package. This package must be built prior to running or building the docs. Descriptions can be updated via the JSON files located in the src/locale/en folder. Some general guidelines to follow when handling api descriptions are:
enlanguage only. Translations are handled via Crowdin.- Prop names should be formatted using bold markdown eg: prop-name.
- Slot and other code related text should be formatted using code markdown eg:
some-slot. - Description keys should be in camelCase, except for
slotkeys which should be kebab-case. - Put keys in alphabetical order.
- Descriptions utilize a hierarchy of
generic.json<Source.json<Component.jsonto reduce duplication. Source can be viewed using the Developer Mode in docs settings.
Adding API Documentation
When creating a new component (or composable, though this is typically done by the Vuetify team), you need to add a corresponding JSON file named ComponentName.json in packages/api-generator/src/locale/en/. This file should contain descriptions for props, slots, events, and exposed methods. After adding or updating JSON files, run pnpm build api to regenerate the dist language files. Keep in mind:
- Changes to Vuetify require a rebuild before building the API
- The API must be built before running the documentation server
Enabling developer mode in the documentation settings will allow you to see the source of truth on API description pages.
Submitting Changes / Pull Requests
First you should create a fork of the vuetify repository to push your changes to. Information on forking repositories can be found in the GitHub documentation.
Then add your fork as a remote in git:
# Using HTTPS
git remote add fork https://github.com/YOUR_USERNAME/vuetify.git
# Using SSH
git remote add fork [email protected]:YOUR_USERNAME/vuetify.gitChoosing a base branch
Before starting development you should know which branch to base your changes on. If in doubt use master as changes to master can usually be merged into a different branch without rebasing.
| Version | Type of change | Branch |
|---|---|---|
| Vuetify 4 | Documentation | master |
| Vuetify 4 | Bug fixes | master |
| Vuetify 4 | New features | dev |
| Vuetify 5 | Features with breaking changes | next |
| Vuetify 3 | Documentation | v3-stable |
| Vuetify 3 | Bug fixes | v3-stable |
| Vuetify 2 | Documentation | v2-stable |
# Switch to the desired branch
# v4
git switch master
# v3
git switch v3-stable
# Pull down any upstream changes
git pull
# Create a new branch to work on
git switch --create fix/1234-some-issue::: warning
Never commit directly to the base branches, always create a feature branch to work on
:::
Commit your changes following our guidelines, then push the branch to your fork with git push -u fork and open a pull request on the Vuetify repository following the provided template.
::: error
Pull requests that include unrelated commits or your local merges will be CLOSED without notice
:::
Working with GitHub
Vuetify's repository lives on GitHub and is the primary location for all development related information.
Some of the more notable links within these services include:
GitHub
The following sections are designed to familiarize you with our standard operating procedures for Vuetify development.
Issue triage
With the size and popularity of Vuetify has come a constant influx of new issues, questions, and feature requests. To organize these requests the Core Team developed tools to aid not only the triaging of issues, but creating them as well.
The Issues board makes heavy use of GitHub's label system with some light automation, such as adding the triage label to new issues.
For Docs - Language
We do not accept PRs for any documentation changes pertaining to languages other than en. All changes for languages other than en are to be submitted through our Crowdin project. You can help translate in one of 2 ways:
- Using in-context translation service directly through the documentation site. To get started simply select
Help Translatein the language drop down in the docs. - Directly through the Crowdin project.
Note: Languages will not be added to the language drop down on the docs site until they have at least 50% of their translations completed.
Requesting new features
Pending
Commit guidelines
All commit messages are required to follow the conventional-changelog standard using the angular preset. This standard format consists of 2 types of commits:
With scope:
<type>(scope): <subject>bashfix(VSelect): don't close when a detachable child is clicked fixes #12354Without scope:
<type>: <subject>bashdocs: restructure nav components Moved duplicated functionality in drawer to reduce scope of responsibility
General Rules
Commit messages must have a subject line and may have body copy. These must be separated by a blank line.
The subject line must not exceed 60 characters
The subject line must be written in imperative mood (fix, not fixed / fixes etc.)
The body copy must include a reference all issues resolved:
bashdocs(sass-variables): fix broken link to api resolves #3219 resolves #3254The body copy must be wrapped at 72 characters
The body copy must only contain explanations as to what and why, never how. The latter belongs in documentation and implementation.
Commit types
The following is a list of commit types used in the angular preset:
- feat: Commits that result in new features or functionalities. Backwards compatible features will release with the next MINOR whereas breaking changes will be in the next MAJOR. The body of a commit with breaking changes must begin with
BREAKING CHANGE, followed by a description of how the API has changed. - fix: Commits that provide fixes for bugs within vuetify's codebase.
- docs: Commits that provide updates to the docs.
- style: Commits that do not affect how the code runs, these are simply changes to formatting.
- refactor: Commits that neither fixes a bug nor adds a feature.
- perf: Commits that improve performance.
- test: Commits that add missing or correct existing tests.
- chore: Other commits that don't modify src or test files.
- revert: Commits that revert previous commits.
File: packages/docs/src/pages/en/getting-started/frequently-asked-questions.md
meta:
title: Frequently asked questions
keywords: frequently asked questions, faq
related:
- /introduction/why-vuetify/
- /getting-started/contributing/
- /getting-started/installation/
Frequently asked questions
Stuck on a particular problem? Check some of these common gotchas before creating a ticket. If you still cannot find what you are looking for, you can submit an issue on GitHub or ask in our community.
Questions
The following responses are a collection of common questions asked by the Vuetify community.
What is Vuetify? { #what-is-vuetify }
Vuetify is a Vue.js framework that helps to create beautiful and responsive user interfaces. It includes a wide variety of customizable and reusable components for building modern applications.
Does Vuetify provide support? { #does-vuetify-provide-support }
Vuetify is a free to use Open Source project released under the MIT license. There are multiple ways to receive support for Vuetify:
- Join our Discord Community - (Free/Paid)
- Ask a question on GitHub Discussions - (Free)
- Get Chat Support from Vuetify - (Paid)
What is the difference between Vuetify and Vue? { #what-is-the-difference-between-vuetify-and-vue }
Vuetify is a framework that is built on top of Vue.js. It is a collection of components that can be used to build applications. Vue.js is a JavaScript framework that is used to build user interfaces.
What versions of Vue.js are compatible with Vuetify? { #what-versions-of-vuejs-are-compatible-with-vuetify }
Vuetify is compatible with Vue.js 3.0.0 and above.
Is Vuetify 2 still supported? { #is-vuetify-2-still-supported }
Vuetify 2 reached End of Life (EOL) on January 25th, 2025. For security and commercial support, see our partner, HeroDevs.
Can I use Vuetify with other CSS frameworks? { #can-i-use-vuetify-with-other-css-frameworks }
Yes, you can use Vuetify with other CSS frameworks, but it is typically not recommended. If you are integrating Vuetify into an existing application that is using another CSS framework, you may want to disable the default color and utility generation. See the SASS Variables page for more information.
Can I customize the styling of Vuetify components? { #can-i-customize-the-styling-of-vuetify-components}
Yes, you can customize the styling of Vuetify components using the Global configuration. Vuetify also provides SASS variables that can be overridden to change the look and feel of the components.
Where can I get help with Vuetify? { #where-can-i-get-help-with-vuetify }
If you need help with an issue, please use one of our help channels:
Can I contribute to Vuetify? { #can-i-contribute-to-vuetify }
Yes, we welcome all contributions. Please see our contributing guide for more information.
Can I use Vuetify with server-side rendering? { #can-i-use-vuetify-with-server-side-rendering }
Yes, Vuetify supports server-side rendering. Set the
ssrproperty totruein yourvuetifyconfiguration object.js { resource="src/plugins/vuetify.js" }import { createVuetify } from 'vuetify' export default createVuetify({ ssr: true, })Is there support for Nuxt 3? { #is-there-support-for-nuxt-3 }
Yes, Vuetify 3 is compatible with Nuxt 3 but does not currently have a community Nuxt module.
What is Vuetify Labs? { #what-is-vuetify-labs }
Vuetify Labs is a collection of components that are still in development. They are not considered stable and may change at any time. They are not included in the default Vuetify installation and must be imported individually. See the Labs page for more information.
Does Vuetify have Nightly Builds? { #does-vuetify-have-nightly-builds }
Yes, Vuetify has nightly builds. See the Nightly Builds page for more information.
I found a bug, what should I do? { #i-found-a-bug-what-should-i-do }
Please create a new issue with our Issue Generator. Please make sure to check for existing issues before creating a new one.
Why did Vuetify 3 change
valuetomodel-value?The
valueprop was changed in Vue 3 to support a newv-modelsyntax. See the official Vue docs for more information on Component v-model.Is Vuetify 3 compatible with
@vue/compat?Not directly, you have to set
configureCompat({ MODE: 3 })globally andMODE: 2in each of your components that you want to run in compatibility mode. There will still be some incorrect warnings that can be ignored with the-ATTR_FALSE_VALUEfilter in devtools.
File: packages/docs/src/pages/en/getting-started/release-notes.md
fluid: true
meta:
title: Release notes
keywords: migration, releases, upgrading vuetify
related:
- /introduction/long-term-support/
- /getting-started/contributing/
- /introduction/roadmap/
Release notes
The Vuetify team performs releases on a weekly basis.
File: packages/docs/src/pages/en/getting-started/unit-testing.md
meta:
title: Unit testing
keywords: unit testing vuetify, testing vuetify, vuetify spec tests
related:
- /getting-started/frequently-asked-questions/
- /getting-started/contributing/
- /components/text-fields/
Unit Testing
Add regression protection by adding unit tests to your Vuetify application
Usage
Unit tests are an important (and sometimes ignored) part of developing applications. They help us secure our processes and workflows, ensuring that the most critical parts of our projects are protected from accidental mistakes or oversights in our development.
Because of this, Vue has its own testing utility called vue-test-utils. It provides useful features for interacting with Vue components and works with many popular test runners.
Using Vite
Vite is a fast, opinionated frontend build tool that serves your code via native ES Module imports during dev and bundles it with Rollup for production. It provides a great developer experience and is the recommended build tool for Vuetify applications.
First, update your vite.config.js file to inline the vuetify dependency:
import { defineConfig } from 'vite'
export default defineConfig({
test: {
globals: true,
environment: 'jsdom',
server: {
deps: {
inline: ['vuetify'],
},
},
},
})Setup Vitest
Vitest is a popular test runner that provides a great developer experience. It is fast, easy to use, and provides useful features like snapshot testing. To get started, install the following dependencies:
::: tabs
pnpm add @vue/test-utils vitest resize-observer-polyfill --save-devyarn add @vue/test-utils vitest resize-observer-polyfill --devnpm install @vue/test-utils vitest resize-observer-polyfill --save-devbun add @vue/test-utils vitest resize-observer-polyfill --dev:::
Once installed, create a new folder at the root of your application named tests/spec and add a new file named HelloWorld.spec.js. The following example shows how to setup a basic unit test for a Vuetify component:
import { mount } from '@vue/test-utils'
import { expect, test } from 'vitest'
import { createVuetify } from 'vuetify'
import * as components from 'vuetify/components'
import * as directives from 'vuetify/directives'
import HelloWorld from '../../src/components/HelloWorld.vue'
const vuetify = createVuetify({
components,
directives,
})
global.ResizeObserver = require('resize-observer-polyfill')
test('displays message', () => {
const wrapper = mount({
template: '<v-layout><hello-world></hello-world></v-layout>'
}, {
props: {},
global: {
components: {
HelloWorld,
},
plugins: [vuetify],
}
})
// Assert the rendered text of the component
expect(wrapper.text()).toContain('Components')
})Testing Vuetify Components
When testing Vuetify components, we recommend running tests in a real browser environment instead of jsdom.
Recommended Test Runners
- Vitest (browser mode) โ Fast, Vite-native test runner with browser support.
- Playwright โ End-to-end testing in actual browsers.
- Cypress โ Great for integration and E2E tests.
Rendering with Vuetify
To properly render Vuetify components in tests, create a Vuetify instance and pass it to the test renderer. You donโt need to mock transitions or other internals.
export function render<C> (
component: C,
options?: RenderOptions<C> | null,
vuetifyOptions?: VuetifyOptions
): RenderResult {
const vuetify = createVuetify(mergeDeep({ icons: { aliases } }, vuetifyOptions))
const defaultOptions = {
global: {
stubs: {
transition: false,
'transition-group': false,
},
plugins: [vuetify],
},
}
const mountOptions = mergeDeep(defaultOptions, options!, (a, b) => a.concat(b))
return _render(component, mountOptions)
}Using `data-testid`
For reliable queries in tests, use data-testid attributes in your components:
<v-btn data-testid="submit-btn">Submit</v-btn>const { getByTestId } = render(MyComponent)
expect(getByTestId('submit-btn')).toBeInTheDocument()Accessibility Considerations
Tests should respect user accessibility preferences. Configure prefers-reduced-motion when testing animations to avoid flakiness and ensure accessibility compliance.
File: packages/docs/src/pages/en/getting-started/upgrade-guide.md
meta:
nav: Upgrade guide
title: Upgrade guide
keywords: migration, upgrade, releases, upgrading vuetify, alpha, v4
related:
- /introduction/roadmap/
- /introduction/long-term-support/
- /introduction/enterprise-support/
Upgrade Guide
This page contains a detailed list of breaking changes and the steps required to upgrade your application to Vuetify 4
Quick Start with Vuetify MCP
The fastest way to check your project for breaking changes is with Vuetify MCP. To get started, run the following in your terminal:
# Claude Code
claude mcp add --transport http vuetify-mcp https://mcp.vuetifyjs.com/mcp
# Configure for hosted remote server
npx -y @vuetify/mcp config --remote
# Or configure for local installation
npx -y @vuetify/mcp configOnce the MCP server is set up and loaded you will gain access to new tools such as:
get_upgrade_guide: Get a list of all breaking changes in the upgrade guide.get_v4_breaking_changes: Get a list of all breaking changes in Vuetify 4.
Now, prompt your agent with the following:
Using the vuetify-mcp server, scan this project for Vuetify 3 to 4 breaking changes. List each issue found with the file, line number, and recommended fix.This will automatically analyze your codebase and provide a tailored list of changes you need to make.
If you have any questions about the upgrade process, come visit us at community.vuetifyjs.com.
Multi-step migration
Several breaking changes in Vuetify 4 can be temporarily reverted by pasting short CSS or configuration snippets โ notably CSS reset, typography, elevation, and grid. This means you can migrate incrementally: restore the legacy behavior first, then update each area at your own pace.
Even though these migrations mostly come down to adjusting CSS classes, manually reviewing every affected template can be time-consuming without automated visual regression tests. For large projects (typically over 200 components), we recommend scanning your codebase for relevant usage before starting:
- HTML elements โ
<h1>through<h6>(affected by CSS reset) - Grid usage โ
<v-row>and<v-col>, with specific focus on ad-hoc spacing adjustments (i.e. classes likemx-0,pa-0) - Grid attributes โ
dense,align,justify,order,align-self(affected by grid changes) - Shadows โ
elevation-*classes andelevationattributes or CSS overrides (affected by elevation changes) - CSS classes โ
text-h1โฆtext-h6,text-subtitle-1,text-body-2,text-caption,text-overline,elevation-*,offset-*(affected by typography)
Identify the areas with the highest usage first, apply the corresponding compatibility snippets, and then schedule the full class-by-class migration as a follow-up.
Sections tagged with
Styles
Style entry points
There are now pre-compiled entry points for the most common style changes. If you have a Sass file that only sets $color-pack: false or $utilities: false you can replace it with import 'vuetify/styles/core'. See Style entry points for more information.
CSS reset
The CSS reset has been mostly removed, with style normalisation being moved to individual components instead. You can inspect the exact changes to learn more. Here is the high level overview:
- global
* { padding: 0; margin: 0; }is gone - no longer resets all elements ,,<select>have their browser-native borders and background colors.
If you notice browser styles adding unnecessary spaces and impact text size, it is recommended to assess the scope of visual regression and selectively apply spacing resets:
@layer vuetify-core.reset {
ul, ol, figure, details, summary {
padding: 0;
margin: 0;
}
h1, h2, h3, h4, h5, h6, p {
margin: 0;
}
}Restoring most of the previous reset styles would be heavy-handed, but will get the job done as well.
@layer vuetify-core.reset {
* { padding: 0; margin: 0; }
a:active, a:hover { outline-width: 0; }
code, kbd, pre, samp { font-family: monospace; }
pre { font-size: 1em; }
small { font-size: 80%; }
sub, sup {
font-size: 75%;
line-height: 0;
position: relative;
vertical-align: baseline;
}
sub { bottom: -0.25em; }
sup { top: -0.5em; }
textarea { resize: vertical; }
button,
input,
select,
textarea {
background-color: transparent;
border-style: none;
}
select {
-moz-appearance: none;
-webkit-appearance: none;
}
legend {
display: table;
max-width: 100%;
white-space: normal;
}
}Applying without a build step
The snippets above are plain CSS and do not require Sass compiler โ drop them into any stylesheet, or inline them within <style> block when using the CDN build:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/vuetify@4/dist/vuetify.css">
<style>
@layer vuetify-core.reset {
ul, ol, figure, details, summary { padding: 0; margin: 0; }
h1, h2, h3, h4, h5, h6, p { margin: 0; }
}
</style>Place the <style> block after Vuetify's stylesheet so the layer order declared in vuetify.css takes effect first. Subsequent @layer vuetify-core.reset { โฆ } rules append to the existing layer and won't override component styles.
Layers
Cascade layers are now being used everywhere. If you have other styles that are not using @layer they will now always take priority over vuetify.
If you were already using $layers: true in Vuetify 3, there are now five top-level layers instead of one.
- @layer base, vuetify, overrides;
+ @layer base, vuetify-core, vuetify-components, vuetify-overrides, vuetify-utilities, vuetify-final, overrides;If you had any usages of @layer vuetify.* in your styles they should be replaced with your own layer name with an appropriate declaration order.
Layer order declaration must come first
The layer order @layer statement must be imported before any layered CSS is parsed โ including Vuetify's own styles. The browser assigns layer priority the first time a layer name appears, so if Vuetify's styles load first, the browser will establish the order from those, not from your declaration.
Import your layer order statement at the very top of your app entrypoint:
// @layer declaration comes first
import './styles/layers.css'
import 'vuetify/styles'
import { createApp } from 'vue'If you intend to migrate large application, it is recommended to define and adopt your own layers, so that developers can drop !important and gain more control over the stylesheets.
@layer vuetify-core;
@layer vuetify-components;
@layer vuetify-overrides;
@layer my-app-base;
@layer my-app-components;
@layer vuetify-utilities;
@layer my-app-utilities;
@layer vuetify-final;::: warning
If this import is missing or appears after Vuetify styles, reset styles or earlier-declared layers may unexpectedly override component styles. Symptoms vary per app depending on build output order, making it difficult to diagnose. This is often caused by Vite v8.x and/or vue-router v5.x.
Note: using @vuetify/cli with init command to generate a working project for comparison is usually the fastest way to effectively troubleshoot the problems.
:::
Typography {codemod-available}
The typography system has been updated from Material Design 2 to Material Design 3. The following replacements will have some minor font size differences:
| MD2 (Legacy) | MD3 (New) |
|---|---|
text-h1 |
text-display-large (96px โ 60px) |
text-h2 |
text-display-large |
text-h3 |
text-display-medium |
text-h4 |
text-headline-large |
text-h5 |
text-headline-small |
text-h6 |
text-title-large |
text-subtitle-1 |
text-body-large |
text-subtitle-2 |
text-title-small |
text-body-1 |
text-body-large |
text-body-2 |
text-body-medium |
text-button |
text-label-large (No uppercase) |
text-caption |
text-body-small |
text-overline |
text-label-medium (No uppercase) |
For detailed mapping and migration instructions, see Typography Migration.
Breakpoints
The default breakpoints have been reduced to better match modern device sizes:
| Breakpoint | Change |
|---|---|
| xs | 0 (unchanged) |
| sm | 600px (unchanged) |
| md | |
| lg | |
| xl | |
| xxl |
One of the components specifically impacted by those changes is VContainer. See the detailed information about those changes below.
v3 breakpoints can be restored with the following configuration:
export default createVuetify({
display: {
thresholds: {
md: 960,
lg: 1280,
xl: 1920,
xxl: 2560,
},
},
})@use 'vuetify/settings' with (
$grid-breakpoints: (
'md': 960px,
'lg': 1280px,
'xl': 1920px,
'xxl': 2560px,
),
);Elevation {codemod-available}
Elevation classes (shadows) have been updated to Material Design 3 which uses 6 levels (0-5) instead of 25 (0-24).
| MD3 elevation levels |
|---|
elevation-0 (0dp) |
elevation-1 (1dp) |
elevation-2 (3dp) |
elevation-3 (6dp) |
elevation-4 (8dp) |
elevation-5 (12dp) |
* "dp" (density-independent pixels) is a relative unit from Material Design
See Elevation migration for details and tips to restore legacy MD2 levels if needed.
Themes
The default theme has been changed from light to system. This means that the default theme will now be the same as the user's system preference. You can change this by setting the defaultTheme theme option:
export default createVuetify({
+ theme: {
+ defaultTheme: 'light',
+ },
})Theme colors now support transparency. rgb(var(--v-theme-color)) will continue to work the same as before, but rgba(var(--v-theme-color), 0.8) should be changed to either color-mix(in srgb, rgb(var(--v-theme-color)) 80%, transparent) or rgb(from rgb(var(--v-theme-color)) / 0.8) when used with a transparent theme color.
Components
VBtn display
In Vuetify 3, VField's layout was changed from display: flex to display: grid to better handle its internal elements. However, the grid implementation had limitations with gap control, so in Vuetify 4 we've reverted back to using display: flex.
The $button-stacked-icon-margin Sass variable has been removed and replaced with $button-stacked-gap. This change allows for more consistent and flexible spacing between elements within the field. If you modified this value, update its variable target:
@use 'vuetify/settings' with (
- $button-stacked-icon-margin: 8px,
+ $button-stacked-gap,
);VBtn text-transform
The default text-transform of uppercase has been removed. To restore the previous behavior, set the text-transform prop to uppercase.
- Set it in the Sass variables for buttons:
@use 'vuetify/settings' with (
$button-text-transform: 'uppercase',
)- Set it as a global default:
import { createVuetify } from 'vuetify'
const vuetify = createVuetify({
defaults: {
VBtn: {
class: 'text-uppercase',
// or if you are using $utilities: false
style: 'text-transform: uppercase;',
},
},
})- Manually type uppercase letters:
- <v-btn>button</v-btn>
+ <v-btn>BUTTON</v-btn>VBadge
The $badge-dot-border-radius Sass variable has been changed from 4.5px to 50%. Both values produce the same result for the default dot size. If your app increases dot size and prefer them square-ish, you might want to undo the change.
@use 'vuetify/settings' with (
- $badge-dot-border-radius: 4.5px,
+ $badge-dot-border-radius: 50%,
);VContainer
Container component won't center the content vertically when paired with fill-height. If you depend on this behavior, you can supplement the missing styles with utility classes:
<v-container
- class="fill-height"
+ class="fill-height d-flex align-center flex-wrap"
/>Max widths
The calculation for $container-max-widths has changed to round values down to the nearest 100px for more predictable sizing. With the default breakpoints, this results in the following container widths:
| Breakpoint | Change |
|---|---|
| md | |
| lg | |
| xl | |
| xxl |
VCounter
VCounter is used to display the counter hint under VTextField, VTextarea and VFieldInput. The $counter-color and color was replaced in favor of opacity. If you modified this value, move it to target CSS class directly:
.v-counter {
opacity: 1;
color: /* your $counter-color */;
}VDatePicker
multiple="range" emits only the start and end dates instead of everything in between. Use something like date-fns' eachDayOfInterval if you need all dates in the range.
- ['2023-09-28', '2023-09-29', '2023-09-30', '2023-10-01', '2023-10-02']
+ ['2023-09-28', '2023-10-02']VFileInput
Removed the $file-input-details-padding-inline Sass variable.
@use 'vuetify/settings' with (
- $file-input-details-padding-inline: <value>
+ $input-details-padding-inline: <value>
);VForm {codemod-available}
Slot variables are no longer refs, read-only values passed to slots are now unwrapped:
<VForm>
<template #default="{ isValid, validate }">
<VBtn @click="validate" text="validate" />
- Form is {{ isValid.value ? 'valid' : 'invalid' }}
+ Form is {{ isValid ? 'valid' : 'invalid' }}
</template>
</VForm>The following properties are affected:
- errors
- isDisabled
- isReadonly
- isValidating
- isValid
- items
VRadioGroup
Removed the $radio-group-details-padding-inline Sass variable.
@use 'vuetify/settings' with (
- $radio-group-details-padding-inline: <value>
+ $input-details-padding-inline: <value>
);VSelect/VCombobox/VAutocomplete {codemod-available}
item in slots has been renamed to internalItem for consistency with VList and VDataTable. item is still available but is now an alias for internalItem.raw which seems like the most common use case.
You can rename:
<VSelect item-title="name">
- <template #item="{ item, props }">
- <VListItem v-bind="props" :title="item.title" />
+ <template #item="{ internalItem, props }">
+ <VListItem v-bind="props" :title="internalItem.title" />
</template>
</VSelect>Or alias:
<VSelect>
- <template #item="{ item, props }">
+ <template #item="{ internalItem: item, props }">
<VListItem v-bind="props" :title="item.raw.name" />
</template>
</VSelect>Or remove .raw:
<VSelect>
<template #item="{ item, props }">
- <VListItem v-bind="props" :title="item.raw.name" />
+ <VListItem v-bind="props" :title="item.name" />
</template>
</VSelect>VSnackbar {codemod-available}
::: warning
This component has its internal HTML structure overhauled to incorporate header and prepend slots
:::
Removed the multi-line prop and the $snackbar-multi-line-wrapper-min-height Sass variable. It can be replaced with min-height equivalent.
<VSnackbar
v-model="visible"
- multi-line
+ min-height="68"
:text="message"
/>VSnackbarQueue {codemod-available}
::: warning
This component has been rewritten to enable showing multiple snackbars at once
:::
The default slot has been renamed to item. The slot props remain the same.
<v-snackbar-queue v-model="messages">
- <template v-slot:default="{ item }">
+ <template v-slot:item="{ item }">
<v-snackbar v-bind="item" />
</template>
</v-snackbar-queue>VTextField
Removed the $text-field-details-padding-inline Sass variable.
@use 'vuetify/settings' with (
- $text-field-details-padding-inline: <value>
+ $input-details-padding-inline: <value>
);Grid System (VRow and VCol)
The grid system has been refactored to use CSS gap instead of negative margins on rows and padding on columns. This change provides more flexibility and predictable spacing behavior.
Layout mechanism changes
| Previous | New |
|---|---|
Negative margins (margin: -12px) |
No margins on VRow |
| Gaps from padding | No default padding, utilizes CSS gap |
Widths from hardcoded percentage (e.g., 75% for .v-col-9) |
Calculated width accounting for gaps |
Prop changes on VRow {codemod-available}
| Previous | New |
|---|---|
dense |
density="compact" or gap="8" |
align prop on VRow |
use utility class (e.g., align-start) |
justify prop on VRow |
use utility class (e.g., justify-center) |
align-content prop on VRow |
use utility class (e.g., align-content-center) |
align-sm, justify-md, etc. |
use responsive utility classes |
| no fine-grained control over gap | gap prop accepts number, string, or [x, y] |
Prop changes on VCol {codemod-available}
| Previous | New |
|---|---|
order prop on VCol |
use utility class (e.g., order-1) |
props like order-sm, order-md, etc. |
use responsive utility classes (e.g., order-sm-1) |
align-self prop on VCol |
use utility class (e.g., align-self-center) |
.offset-{n} (offset classes) |
offset prop |
Alignment (VRow):
- <v-row align="center" justify="space-between">
+ <v-row class="align-center justify-space-between">Responsive alignment:
- <v-row align-sm="start" align-md="center" justify-lg="end">
+ <v-row class="align-sm-start align-md-center justify-lg-end">Order (VCol):
- <v-col order="2" order-md="1">
+ <v-col class="order-2 order-md-1">Align self (VCol):
- <v-col align-self="center">
+ <v-col class="align-self-center">Dense rows:
- <v-row dense>
+ <v-row density="compact">Offset class changes
Offset classes have been renamed from .offset-* to .v-col-offset-* for namespace consistency:
- <v-col offset="3" offset-md="2">
+ <v-col offset="3" offset-md="2">The component props (offset, offset-sm, etc.) continue to work unchanged, but if you were using the CSS classes directly, update them:
-
+Sass variables cleanup
$form-grid-gutter was replaced with $grid-density. New values subtract values from the default gutter
- $form-grid-gutter: $spacer * 2 !default;
+ $grid-density: ('default': 0, 'comfortable': -1, 'compact': -2) !default;Sass variable $grid-gutters was removed. If your existing project had some custom definition set for this variable, you might want to adjust the variables below:
@use 'vuetify/settings' with (
$avatar-margin-end: 8px;
$avatar-margin-start: 8px;
$icon-left-margin-left: 8px;
$icon-margin-end: 8px;
$icon-margin-start: 8px;
$icon-btn-margin-start: 8px;
$icon-btn-margin-end: 8px;
}Restoring the legacy grid behavior
If you need to maintain the previous grid behavior (negative margins and column padding), see the Grid Legacy Mode guide.
Tooling
Vite: overlay z-index in dev mode
Vuetify 4 calculates overlay z-index through a shared useStack singleton โ when a dialog opens at 2400, any overlay rendered inside it (a select menu, a tooltip, etc.) automatically stacks at 2410. This works correctly in production, but can silently break in Vite dev mode.
Symptom: Menus, selects, or other overlays opened inside a dialog appear behind it โ they render, but are invisible because they sit at the default z-index (2000) instead of stacking above the dialog.
Root cause: Vite's dependency pre-bundler can serve some Vuetify modules from its optimized cache and others from raw ESM. When this split happens, two separate useStack instances are created. Each overlay registers with its own instance, so they never see each other's stack โ and auto-stacking stops working.
Fix: Force Vite to pre-bundle Vuetify's overlay-related modules consistently, then clear the cache:
export default defineConfig({
optimizeDeps: {
include: [
'vuetify/components/VOverlay',
'vuetify/components/VDialog',
'vuetify/components/VMenu',
'vuetify/components/VSelect',
'vuetify/components/VTooltip',
],
},
})After updating the config, delete the .vite cache directory and restart the dev server:
rm -rf node_modules/.viteThis issue only manifests in dev mode. Production builds are not affected because Vite bundles everything into a single module graph.
Defaults
undefined values are now skipped when merging prop defaults. This button would have been grey in v3, but is now green:
createVuetify({
defaults: {
VBtn: { color: 'green' },
},
})
<VDefaultsProvider :defaults="{ VBtn: { color: undefined }}">
<VBtn />
</VDefaultsProvider>Replace undefined with null if you do actually want it to override the global default value.
File: packages/docs/src/pages/en/getting-started/wireframes.md
meta:
title: Wireframes
keywords: pre-defined layouts, layouts, application layout, material design layouts
related:
- /features/application-layout/
- /features/theme/
- /features/blueprints/
Wireframes
The Vuetify layout system makes it easy to rapidly scaffold an application's UI regions with little effort.
Examples
These templates are known as wireframes and are designed to provide a consistent approach to layouts, layering, and shadows. They are a starting point that is meant to be modified to meet the specific needs of your application.
::: info
Additional information on how these templates are structured is located on the Application page.
:::
File: packages/docs/src/pages/en/features/accessibility.md
meta:
title: Accessibility (a11y)
keywords: a11y, accessibility, usability
related:
- /features/internationalization/
- /components/menus/
- /components/lists/
features:
label: 'a11y'
report: true
Accessibility (a11y)
Web accessibility (a11y for short), is the inclusive practice of ensuring there are no barriers that prevent the interaction with, or access to, websites on the World Wide Web by people with disabilities. Vuetify components are built to provide keyboard interactions for all mouse-based actions and utilize HTML5 semantic elements where applicable.
Activator slots
Vuetify uses activator slots for many components such as v-menu, v-dialog and more. In some instances these activator elements should have specific a11y attributes that associate them with their corresponding content. In order to achieve this, we pass down the necessary a11y options through the slots scope.
<template>
<v-menu>
<template v-slot:activator="{ props }">
<v-btn
text="Click me"
v-bind="props"
></v-btn>
</template>
<v-list>
<v-list-item @click="method">
<v-list-item-title>Option 1</v-list-item-title>
</v-list-item>
<v-list-item disabled>
<v-list-item-title>Option 2</v-list-item-title>
</v-list-item>
<v-list-item @click="method">
<v-list-item-title>Option 3</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</template>When the activator element is rendered, it will now contain the bound a11y attributes:
Click meFocus management and keyboard interactions
Beyond attributes, components such as v-menu also support interaction by pressing โ and โ for navigating between options.
v-menu
When inside of a v-menu, v-list-item will be automatically configured to have a role of menuitem. Navigate to the Menu for more information on the components features.
Additional Resources
While Vuetify attempts to make a11y as easy as possible in your application, there are times where additional information is needed. Below you can find a list of helpful resources.