Pulled ALL skills from 15 source repositories: - anthropics/skills: 16 (docs, design, MCP, testing) - obra/superpowers: 14 (TDD, debugging, agents, planning) - coreyhaines31/marketingskills: 25 (marketing, CRO, SEO, growth) - better-auth/skills: 5 (auth patterns) - vercel-labs/agent-skills: 5 (React, design, Vercel) - antfu/skills: 16 (Vue, Vite, Vitest, pnpm, Turborepo) - Plus 13 individual skills from various repos Mosaic Stack is not limited to coding — the Orchestrator and subagents serve coding, business, design, marketing, writing, logistics, analysis, and more. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
4.5 KiB
4.5 KiB
Plugin Structure: Install Method Requirements
Rule
A Vue plugin must be either an object with an install() method, or a function that serves as the install function. The install function receives the app instance and optional user-provided options.
Why This Matters
-
API contract: Vue's
app.use()expects a specific interface. Incorrect structure causes silent failures or errors. -
Options passing: The install method receives options that users pass to
app.use(), enabling plugin configuration. -
App access: The install method receives the app instance, providing access to
app.component(),app.directive(),app.provide(), etc.
Plugin Structures
Object with install method (recommended)
// plugins/myPlugin.ts
import type { App } from 'vue'
interface PluginOptions {
prefix?: string
debug?: boolean
}
const myPlugin = {
install(app: App, options: PluginOptions = {}) {
const { prefix = 'my', debug = false } = options
if (debug) {
console.log('Installing myPlugin with prefix:', prefix)
}
app.provide('myPlugin', { prefix })
}
}
export default myPlugin
// Usage
app.use(myPlugin, { prefix: 'custom', debug: true })
Function as install (alternative)
// plugins/simplePlugin.ts
import type { App } from 'vue'
function simplePlugin(app: App, options?: { message: string }) {
app.config.globalProperties.$greet = () => {
return options?.message ?? 'Hello!'
}
}
export default simplePlugin
// Usage
app.use(simplePlugin, { message: 'Welcome!' })
Factory function pattern (most flexible)
// plugins/configuredPlugin.ts
import type { App, Plugin } from 'vue'
interface I18nOptions {
locale: string
messages: Record<string, Record<string, string>>
fallbackLocale?: string
}
export function createI18n(options: I18nOptions): Plugin {
return {
install(app: App) {
// Options are captured in closure - no need to pass through app.use()
const { locale, messages, fallbackLocale = 'en' } = options
const translate = (key: string): string => {
return messages[locale]?.[key]
?? messages[fallbackLocale]?.[key]
?? key
}
app.provide('i18n', { translate, locale })
}
}
}
// Usage - options passed to factory, not app.use()
const i18n = createI18n({
locale: 'fr',
messages: {
en: { hello: 'Hello' },
fr: { hello: 'Bonjour' }
}
})
app.use(i18n) // No second argument needed
Common Plugin Capabilities
const fullFeaturedPlugin = {
install(app: App, options: PluginOptions) {
// 1. Register global components
app.component('MyButton', MyButtonComponent)
app.component('MyInput', MyInputComponent)
// 2. Register global directives
app.directive('focus', focusDirective)
// 3. Provide injectable values (recommended)
app.provide('pluginConfig', options)
// 4. Add global properties (use sparingly)
app.config.globalProperties.$myHelper = helperFunction
// 5. Add global mixins (avoid if possible)
app.mixin({
created() {
// Runs for every component
}
})
// 6. Custom error handling
app.config.errorHandler = (err, vm, info) => {
// Handle errors
}
}
}
TypeScript: Plugin Type
Use the Plugin type for proper typing:
import type { App, Plugin } from 'vue'
// With options type parameter
interface MyOptions {
apiKey: string
}
const myPlugin: Plugin<[MyOptions]> = {
install(app: App, options: MyOptions) {
// options is typed as MyOptions
}
}
// Without options
const simplePlugin: Plugin = {
install(app: App) {
// No options expected
}
}
Common Mistakes
Missing install method
// BAD - This is just an object, not a plugin
const notAPlugin = {
doSomething() { /* ... */ }
}
app.use(notAPlugin) // Error or silent failure
// GOOD
const actualPlugin = {
install(app) {
app.provide('service', { doSomething() { /* ... */ } })
}
}
Forgetting to use the app parameter
// BAD - Does nothing
const uselessPlugin = {
install(app, options) {
const service = createService(options)
// Forgot to register anything with app!
}
}
// GOOD
const usefulPlugin = {
install(app, options) {
const service = createService(options)
app.provide('service', service) // Actually makes it available
}
}