Nuxt
Using Pinia with Nuxt is easier since Nuxt takes care of a lot of things when it comes to server side rendering. For instance, you don't need to care about serialization nor XSS attacks. Pinia supports Nuxt 3 and 4.
Installation
npx nuxi@latest module add pinia
This will add both @pinia/nuxt
and pinia
to your project. If you notice that pinia
is not installed, please install it manually with your package manager: npm i pinia
.
TIP
If you're using npm, you might encounter an ERESOLVE unable to resolve dependency tree error. In that case, add the following to your package.json
:
"overrides": {
"vue": "latest"
}
We supply a module to handle everything for you, you only need to add it to modules
in your nuxt.config.js
file:
// nuxt.config.js
export default defineNuxtConfig({
// ... other options
modules: [
// ...
'@pinia/nuxt',
],
})
And that's it, use your store as usual!
Awaiting for actions in pages
As with onServerPrefetch()
, you can call a store action within the callOnce()
composable. This will allow Nuxt to run the action only once and avoids refetching data that is already present.
<script setup>
const store = useStore()
// we could also extract the data, but it's already present in the store
await callOnce('user', () => store.fetchUser())
</script>
Depending on your requirements, you can choose to run the action only once on the client, or on every navigation (which is closer to data fetching behavior of useFetch()
/useAsyncData()
)
<script setup>
const store = useStore()
await callOnce('user', () => store.fetchUser(), { mode: 'navigation' })
</script>
TIP
If you want to use a store outside of setup()
or an injection aware context (e.g. Navigation guards, other stores, Nuxt Middlewares, etc), remember to pass the pinia
instance to useStore()
, for the reasons alluded to here. Retrieving the pinia
instance might vary.
import { useStore } from '~/stores/myStore'
// this line is usually inside a function that is able to retrieve
// the pinia instance
const store = useStore(pinia)
Fortunately, most of the time you don't need to go through this hassle.
Auto imports
By default @pinia/nuxt
exposes a few auto imports:
usePinia()
, which is similar togetActivePinia()
but works better with Nuxt.defineStore()
to define storesstoreToRefs()
when you need to extract individual refs from a storeacceptHMRUpdate()
for hot module replacement
It also automatically imports all stores defined within your stores
folder (app/stores
in Nuxt 4). It doesn't lookup for nested stores though. You can customize this behavior by setting the storesDirs
option:
// nuxt.config.ts
export default defineNuxtConfig({
// ... other options
modules: ['@pinia/nuxt'],
pinia: {
storesDirs: ['./stores/**', './custom-folder/stores/**'],
},
})
Note the folders are relative to the root of your project. If you change the srcDir
option, you need to adapt the paths accordingly.