Setting the file. One moment.
Subchapter 5.4
references/best-practices-outside-component.mdMarkdown2 KBView on GitHub
Stores need the pinia instance, which is automatically injected in components. Outside components, you may need to provide it manually.
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()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'
}
})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'
}
})Access pinia via this.$pinia:
export default {
serverPrefetch() {
const store = useStore(this.$pinia)
return store.fetchData()
},
}Works normally in <script setup>:
<script setup>
const store = useStore()
onServerPrefetch(async () => {
// ✅ Just works
await store.fetchData()
})
</script>Defer useStore() calls to functions that run after pinia is installed, rather than calling at module scope.