Configurable persistence and rehydration of Pinia stores.
- Persist Pinia stores with the same API as
vuex-persistedstate
. - Configurable per Pinia store.
- Still compatible with Vue 2 and 3.
- Super small (<1kB).
- Install with your favourite package manager (pnpm, npm, yarn).
- Add the plugin to pinia:
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
You just need to add the persist
option to the store you want to be persisted as follows:
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state: () => {
return {
someState: 'hello pinia',
}
},
persist: true
})
In case you want to configure how the data should be persisted, persist
can take options:
key: string
: Key to use in storage (defaults to the current store id).storage
: Storage like object to persist state to. Must havegetItem
,setItem
andremoveItem
methods (defaults tolocalStorage
).paths: Array<string>
: Array of dot-notation paths to partially persist the state,[]
means no state is persisted (defaults toundefined
and persists the whole state).overwrite: boolean
: Whether you want to ovewrite the initial state on hydration (defaults tofalse
and patches the state).beforeRestore: (context) => void
: Hook executed (if set) before restoring the state from localstorage.afterRestore: (context) => void
: Hook executed (if set) after restoring the state from localstorage.
import { defineStore } from 'pinia'
export const useStore = defineStore('main', {
state: () => {
return {
someState: 'hello pinia',
nested: {
data: 'nested pinia',
},
}
},
persist: {
key: 'storekey',
storage: window.sessionStorage,
paths: ['nested.data'],
overwrite: true,
beforeRestore: (context) => {
console.log('Before hydration...')
},
afterRestore: ({ store }) => {
store.lastReload = new Date().toString()
}),
}
})
The config above will only persist the nested.data
property in sessionStorage
under storekey
and will overwrite the state on hydration.
It will also execute the beforeRestore
and afterRestore
hooks before/after hydration.
References do not persist
Beware of the following:
const a = {
1: 'one',
2: 'two',
...
}
const b = a
// Before hydration 'a' and 'b'
// point to the same object:
a === b -> true
// After hydration (page reload)
// 'a' and 'b' are different objects
// with the same content:
a === b -> false
As a consequence, reactivity between a and b is lost.
To get around this you can exclude either a or b from persisting and use the afterRestore()
hook to populate them after hydration. That way a and b have the same reference again and reactivity is restored after page reload.
This project tries to bring vuex-persistedstate
's API to Pinia
but I did not bring the whole API yet.
Run into a problem? Open an issue. Want to add some feature? PRs are welcome!
Feel free to contact me:
Copyright © 2021 Sacha Bouillez.
This project is under MIT license.