--- name: using-stores-outside-components description: Correctly using stores in navigation guards, plugins, and other non-component contexts --- # Using Stores Outside Components Stores need the `pinia` instance, which is automatically injected in components. Outside components, you may need to provide it manually. ## Single Page Applications Call stores **after** pinia is installed: ```ts import { useUserStore } from '@/stores/user' import { createPinia } from 'pinia' import { createApp } from 'vue' import App from './App.vue' // ❌ Fails - pinia not created yet const userStore = useUserStore() const pinia = createPinia() const app = createApp(App) app.use(pinia) // ✅ Works - pinia is active const userStore = useUserStore() ``` ## Navigation Guards **Wrong:** Call at module level ```ts import { createRouter } from 'vue-router' const router = createRouter({ /* ... */ }) // ❌ May fail depending on import order const store = useUserStore() router.beforeEach((to) => { if (store.isLoggedIn) { /* ... */ } }) ``` **Correct:** Call inside the guard ```ts router.beforeEach((to) => { // ✅ Called after pinia is installed const store = useUserStore() if (to.meta.requiresAuth && !store.isLoggedIn) { return '/login' } }) ``` ## SSR Applications Always pass the `pinia` instance to `useStore()`: ```ts const pinia = createPinia() const app = createApp(App) app.use(router) app.use(pinia) router.beforeEach((to) => { // ✅ Pass pinia instance const main = useMainStore(pinia) if (to.meta.requiresAuth && !main.isLoggedIn) { return '/login' } }) ``` ## serverPrefetch() Access pinia via `this.$pinia`: ```ts export default { serverPrefetch() { const store = useStore(this.$pinia) return store.fetchData() }, } ``` ## onServerPrefetch() Works normally in ` ``` ## Key Takeaway Defer `useStore()` calls to functions that run after pinia is installed, rather than calling at module scope.