Files
fuel-price/.agents/skills/pinia/references/best-practices-outside-component.md
Ovidiu U 4a3ce4cc1d
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (8.3) (push) Has been cancelled
tests / ci (8.4) (push) Has been cancelled
tests / ci (8.5) (push) Has been cancelled
docs: add advanced skills for Vitest, Pinia, and Vue built-ins
Add comprehensive reference documentation for:
- Vitest: environments, projects/workspaces, type testing, vi utilities
- Pinia: HMR, Nuxt integration, SSR setup
- Vue: built-in components (Transition, Teleport, Suspense, KeepAlive) and advanced directives
2026-04-11 16:28:36 +01:00

116 lines
2.2 KiB
Markdown

---
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 `<script setup>`:
```vue
<script setup>
const store = useStore()
onServerPrefetch(async () => {
// ✅ Just works
await store.fetchData()
})
</script>
```
## Key Takeaway
Defer `useStore()` calls to functions that run after pinia is installed, rather than calling at module scope.
<!--
Source references:
- https://pinia.vuejs.org/core-concepts/outside-component-usage.html
-->