The Dev Tools
Inspect the component tree and live state with Vue DevTools, and read Vite's error overlay instead of guessing at it.
plugins: [vue(), vueDevTools()] // vite.config.tsVue DevTools is an inspector for a running Vue application. It answers what a console log cannot: which components are on screen right now, and what each one is holding.
Getting it
Three forms of the same tool. A browser extension, a standalone application, and a Vite plugin, vite-plugin-vue-devtools, which create-vue can add for you and which opens inside the page. All of them attach only to a development build.
What it shows
The component tree lists mounted components by name, nested the way they render. Select one and you see its props, its refs and its other state, with the matching element highlighted in the page. Most values can be edited in place: change one and the page updates, which is the quickest way to check how a component handles an empty list or a very long name. The timeline records events in the order they happened — components mounting, emitted events, state changes — so you can see whether a handler fired at all.
Reading the overlay
When a file fails to compile, Vite covers the page with an overlay naming the plugin that failed, the file path, the line and column, and a snippet of the offending code. It is the compiler telling you exactly where it stopped. Fix the file and it disappears on save; press Escape to dismiss it meanwhile. The same message is printed in the terminal running the dev server. Runtime errors do not use the overlay: they go to the browser console, with a component trace under the message.
Example
<script setup lang="ts">
import { ref } from 'vue'
const count = ref(0)
const step = ref(1)
function increment() {
count.value += step.value
}
function grow() {
step.value += 1
}
</script>
<template>
<p>Count {{ count }}, step {{ step }}</p>
<button type="button" @click="increment">Add</button>
<button type="button" @click="grow">Bigger step</button>
</template>
<style scoped>
p {
margin: 0 0 0.5rem;
}
</style>When to use it
- Checking what a component is actually holding when the screen looks wrong
- Editing a value live to see how a component renders an empty or extreme case
- Turning a red overlay into a file and line number instead of a guess
- Confirming that a click handler fired by looking at the timeline
More examples
Adding the DevTools plugin to an existing project
Needed only if you answered no to the DevTools prompt when the project was generated, or if the project predates it. It is a dev dependency: it never reaches a production bundle. Check the plugin's own documentation for the config shape of the version you install, since it has changed across majors.
# terminal
npm add -D vite-plugin-vue-devtools
# restart the dev server afterwards
npm run devRegistering it in vite.config.ts
The plugin goes after vue() in the array. Once the dev server restarts, the app gets a small floating panel that opens the inspector in the page, which is handy on a machine where you cannot install a browser extension. Remove the import and the array entry to take it out again.
// vite.config.ts
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import vueDevTools from 'vite-plugin-vue-devtools'
export default defineConfig({
plugins: [vue(), vueDevTools()],
resolve: {
alias: {
'@': fileURLToPath(new URL('./src', import.meta.url)),
},
},
})The shape of a compile error in the overlay
Read it from the bottom up: the caret points at the line the compiler could not make sense of, and the real mistake is usually just above it, here an unclosed <p> on line 8. The bracketed prefix tells you which plugin raised the error, so vite:vue means the SFC compiler rather than your application code.
[plugin:vite:vue] Element is missing end tag.
/Users/dev/my-app/src/components/UserCard.vue:9:3
8 | <p>{{ user.name }}
9 | <p>{{ user.email }}</p>
| ^
10 | </template>
Discussion