What Causes This Warning?
This warning occurs when you call app.use() with the same plugin more than once. Vue prevents duplicate plugin installations to avoid unexpected behavior.
The Problem
// main.js
import { createApp } from 'vue'
import App from './App.vue'
import MyPlugin from './plugins/myPlugin'
const app = createApp(App)
// ❌ Installing the same plugin twice
app.use(MyPlugin)
app.use(MyPlugin) // Warning: Plugin already applied!
app.mount('#app')
The Fix
Remove Duplicate Installation
import { createApp } from 'vue'
import App from './App.vue'
import MyPlugin from './plugins/myPlugin'
const app = createApp(App)
// ✅ Install once
app.use(MyPlugin)
app.mount('#app')
Check Before Installing
const installedPlugins = new Set()
function safeUse(app, plugin, options) {
if (!installedPlugins.has(plugin)) {
app.use(plugin, options)
installedPlugins.add(plugin)
}
}
safeUse(app, MyPlugin)
safeUse(app, MyPlugin) // Safely ignored
Common Scenarios
Multiple Entry Points
// ❌ Plugin installed in multiple files
// plugins/index.js
export function setupPlugins(app) {
app.use(Router)
app.use(Store)
}
// main.js
import { Router } from './router'
import { setupPlugins } from './plugins'
app.use(Router) // Installed here
setupPlugins(app) // And installed again here!
// ✅ Centralize plugin installation
// plugins/index.js
export function setupPlugins(app) {
app.use(Router)
app.use(Store)
}
// main.js
import { setupPlugins } from './plugins'
setupPlugins(app) // Only installed here
Hot Module Replacement (HMR)
// During development with HMR, plugins might be re-applied
// Most plugins handle this internally
// For custom plugins, add a guard
const MyPlugin = {
install(app) {
if (app.config.globalProperties.$myPlugin) {
return // Already installed
}
app.config.globalProperties.$myPlugin = { /* ... */ }
}
}
Conditional Plugin Loading
// ❌ Might install twice with bad logic
if (isDev) {
app.use(DevTools)
}
app.use(DevTools) // Oops!
// ✅ Clear conditional logic
if (isDev) {
app.use(DevTools)
}
// No duplicate installation
Library with Internal Vue Usage
// Some libraries install Vue plugins internally
// Check library documentation
// ❌ Library already installs this
import SomeLibrary from 'some-library'
import { createRouter } from 'vue-router'
app.use(SomeLibrary) // Might install router internally
app.use(createRouter({ /* ... */ })) // Duplicate!
// ✅ Check library docs for included plugins
app.use(SomeLibrary) // Only use library's setup
Creating Plugins with Guards
// Custom plugin with installation guard
const MyPlugin = {
install(app, options = {}) {
// Check if already installed
if (app.__myPluginInstalled) {
console.warn('MyPlugin is already installed')
return
}
// Mark as installed
app.__myPluginInstalled = true
// Plugin logic
app.config.globalProperties.$myHelper = () => {
// ...
}
app.provide('myPlugin', {
// ...
})
}
}
export default MyPlugin
Using Symbol for Installation Check
const INSTALLED_KEY = Symbol('myPlugin')
const MyPlugin = {
install(app) {
if (app[INSTALLED_KEY]) return
app[INSTALLED_KEY] = true
// Installation logic
}
}
Common Plugins That Might Conflict
// Vue Router - only one instance per app
import { createRouter } from 'vue-router'
const router = createRouter({ /* ... */ })
app.use(router)
// Pinia - only install once
import { createPinia } from 'pinia'
const pinia = createPinia()
app.use(pinia)
// Vuetify - has its own installation check
import { createVuetify } from 'vuetify'
const vuetify = createVuetify()
app.use(vuetify)
Quick Checklist
- Check for duplicate
app.use()calls - Centralize plugin installation in one file
- Review library documentation for included plugins
- Add installation guards to custom plugins
- Check for conditional logic that might install twice
- Be aware of HMR behavior during development