Vue Plugins
What are Vue Plugins?
Plugins are self-contained code that adds app-level functionality to Vue. A plugin is an object with an install(app, options) method (or just a function). Plugins can add global components, directives, provide values, or extend the app instance.
Common use cases: i18n (internationalization), toast notifications, analytics, HTTP clients, UI component libraries.
// plugins/toast.js — Toast notification plugin
import { ref, createApp, h } from 'vue'
// Toast component
const ToastComponent = {
props: { message: String, type: String },
template: `
<div :class="['toast', 'toast-' + type]">
{{ message }}
</div>
`
}
// Plugin object
export const ToastPlugin = {
install(app, options = {}) {
const defaultOptions = {
duration: 3000,
position: 'top-right',
...options
}
// Create toast container
const container = document.createElement('div')
container.id = 'toast-container'
document.body.appendChild(container)
// Toast function
function showToast(message, type = 'info') {
const toastApp = createApp(ToastComponent, { message, type })
const el = document.createElement('div')
container.appendChild(el)
toastApp.mount(el)
setTimeout(() => {
toastApp.unmount()
el.remove()
}, defaultOptions.duration)
}
// Provide the toast function globally
app.provide('toast', {
success: (msg) => showToast(msg, 'success'),
error: (msg) => showToast(msg, 'error'),
info: (msg) => showToast(msg, 'info'),
warning: (msg) => showToast(msg, 'warning'),
})
// Also add as global property
app.config.globalProperties.$toast = {
success: (msg) => showToast(msg, 'success'),
error: (msg) => showToast(msg, 'error'),
}
}
}
// Usage in component:
// import { inject } from 'vue'
// const toast = inject('toast')
// toast.success('Saved successfully!')
// toast.error('Something went wrong')
// plugins/i18n.js — Simple internationalization plugin
import { ref, provide, inject } from 'vue'
const I18N_KEY = Symbol('i18n')
export const i18nPlugin = {
install(app, options = {}) {
const { locale = 'en', messages = {} } = options
const currentLocale = ref(locale)
function t(key, params = {}) {
const keys = key.split('.')
let value = messages[currentLocale.value]
for (const k of keys) {
value = value?.[k]
}
if (!value) return key // fallback to key
// Replace {param} placeholders
return value.replace(/\{(\w+)\}/g, (_, param) => params[param] ?? `{${param}}`)
}
function setLocale(newLocale) {
currentLocale.value = newLocale
}
// Provide globally
app.provide(I18N_KEY, { t, currentLocale, setLocale })
// Global property
app.config.globalProperties.$t = t
}
}
// Composable to use in components
export function useI18n() {
return inject(I18N_KEY)
}
// Usage in main.js:
// app.use(i18nPlugin, {
// locale: 'en',
// messages: {
// en: { greeting: 'Hello, {name}!', nav: { home: 'Home' } },
// es: { greeting: '¡Hola, {name}!', nav: { home: 'Inicio' } }
// }
// })
// Usage in component:
// const { t, setLocale } = useI18n()
// t('greeting', { name: 'Alice' }) // 'Hello, Alice!'
// setLocale('es')
// main.js — registering plugins
import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import { createPinia } from 'pinia'
import { ToastPlugin } from './plugins/toast'
import { i18nPlugin } from './plugins/i18n'
// Import third-party plugins
import VueClickAway from 'vue3-click-away'
const app = createApp(App)
// Use plugins — order matters
app.use(createPinia())
app.use(router)
// Custom plugins with options
app.use(ToastPlugin, { duration: 4000, position: 'bottom-right' })
app.use(i18nPlugin, {
locale: 'en',
messages: {
en: {
greeting: 'Hello, {name}!',
nav: { home: 'Home', about: 'About' },
errors: { required: 'This field is required' }
},
fr: {
greeting: 'Bonjour, {name}!',
nav: { home: 'Accueil', about: 'À propos' },
errors: { required: 'Ce champ est obligatoire' }
}
}
})
// Third-party plugin
app.use(VueClickAway)
// Global component registration (often done in plugins)
import BaseButton from './components/BaseButton.vue'
import BaseInput from './components/BaseInput.vue'
app.component('BaseButton', BaseButton)
app.component('BaseInput', BaseInput)
// Global directive registration
import { vFocus } from './directives'
app.directive('focus', vFocus)
app.mount('#app')
Ready to Level Up Your Skills?
Explore 500+ free tutorials across 20+ languages and frameworks.