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

2.2 KiB

name, description
name description
using-stores-outside-components 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:

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

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

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():

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:

export default {
  serverPrefetch() {
    const store = useStore(this.$pinia)
    return store.fetchData()
  },
}

onServerPrefetch()

Works normally in <script setup>:

<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.