Files
agent-skills/skills/vue-best-practices/reference/multiple-app-instances.md
Jason Woltje f5792c40be feat: Complete fleet — 94 skills across 10+ domains
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>
2026-02-16 16:27:42 -06:00

116 lines
3.8 KiB
Markdown

---
title: Use Multiple App Instances for Partial Page Control
impact: MEDIUM
impactDescription: Mounting single app to entire page when only controlling parts wastes resources and complicates SSR
type: efficiency
tags: [vue3, createApp, mount, ssr, progressive-enhancement, architecture]
---
# Use Multiple App Instances for Partial Page Control
**Impact: MEDIUM** - When Vue only controls specific parts of a page (common with server-rendered HTML or progressive enhancement), mounting a single large app instance to the entire page is inefficient and can complicate server-side rendering integration.
Vue's `createApp` API explicitly supports multiple application instances on the same page. Each instance has its own isolated scope for configuration and global assets, making this pattern safe and recommended.
## Task Checklist
- [ ] Assess whether Vue controls the entire page or just specific parts
- [ ] For partial control, create separate app instances for each Vue-managed section
- [ ] Each instance can have its own plugins, components, and configuration
- [ ] Consider shared state via external stores if instances need to communicate
**Incorrect:**
```javascript
// Server-rendered page with Vue only needed for a few interactive widgets
// WRONG: Mounting to entire page
// index.html (server-rendered)
// <body id="app">
// <header>...</header> <!-- static -->
// <nav>...</nav> <!-- static -->
// <div class="widget-1">...</div> <!-- needs Vue -->
// <main>...</main> <!-- static -->
// <div class="widget-2">...</div> <!-- needs Vue -->
// <footer>...</footer> <!-- static -->
// </body>
import { createApp } from 'vue'
import BigApp from './BigApp.vue'
// WRONG: Vue now controls entire page, including static content
createApp(BigApp).mount('#app')
```
**Correct:**
```javascript
// CORRECT: Mount separate instances to specific elements
import { createApp } from 'vue'
import SearchWidget from './widgets/SearchWidget.vue'
import CartWidget from './widgets/CartWidget.vue'
import { createPinia } from 'pinia'
// Shared store for cross-widget state
const pinia = createPinia()
// Widget 1: Search functionality
const searchApp = createApp(SearchWidget)
searchApp.use(pinia)
searchApp.mount('.widget-search')
// Widget 2: Shopping cart
const cartApp = createApp(CartWidget)
cartApp.use(pinia) // Same Pinia instance = shared state
cartApp.mount('.widget-cart')
// Rest of page remains server-rendered static HTML
```
## Benefits of Multiple Instances
```javascript
// 1. Isolated configuration per section
const adminApp = createApp(AdminPanel)
adminApp.config.errorHandler = adminErrorHandler
adminApp.use(adminOnlyPlugin)
adminApp.mount('#admin-panel')
const publicApp = createApp(PublicWidget)
publicApp.config.errorHandler = publicErrorHandler
// Different plugins, components, configuration
publicApp.mount('#public-widget')
// 2. Independent lifecycle
// Can unmount/remount sections independently
const app1 = createApp(Widget1).mount('#widget-1')
const app2 = createApp(Widget2).mount('#widget-2')
// Later, unmount just one widget
// app1.$destroy() in Vue 2, use app.unmount() for the app instance in Vue 3
```
## Shared State Between Instances
```javascript
// Option 1: Shared Pinia store
const pinia = createPinia()
createApp(App1).use(pinia).mount('#app1')
createApp(App2).use(pinia).mount('#app2')
// Both apps share the same Pinia stores
// Option 2: Shared reactive state module
// sharedState.js
import { reactive } from 'vue'
export const sharedState = reactive({
user: null,
cart: []
})
// Both apps import and use sharedState directly
```
## Reference
- [Vue.js - Multiple Application Instances](https://vuejs.org/guide/essentials/application.html#multiple-application-instances)
- [Vue.js Application API](https://vuejs.org/api/application.html)