0
# Store Persistence
1
2
Configuration options for individual store persistence behavior, including storage selection, state filtering, and lifecycle hooks. Each store can configure its own persistence settings independently of global plugin options.
3
4
## Capabilities
5
6
### Persistence Configuration
7
8
Configure how individual stores persist their state with fine-grained control over storage, serialization, and state selection.
9
10
```typescript { .api }
11
/**
12
* Persistence options for individual stores
13
*/
14
interface PersistenceOptions<State = any> {
15
/** Storage key to use (defaults to store.$id) */
16
key?: string;
17
/** Enable debug logging for this store */
18
debug?: boolean;
19
/** Storage backend for this store */
20
storage?: StorageLike;
21
/** Serializer for state conversion */
22
serializer?: Serializer;
23
/** Hook called before hydrating store */
24
beforeHydrate?: (context: PiniaPluginContext) => void;
25
/** Hook called after hydrating store */
26
afterHydrate?: (context: PiniaPluginContext) => void;
27
/** Dot-notation paths to include in persistence */
28
pick?: Path<State>[] | string[];
29
/** Dot-notation paths to exclude from persistence */
30
omit?: Path<State>[] | string[];
31
}
32
33
/**
34
* Dot-notation path type for deep object property access
35
*/
36
type Path<T> = string;
37
38
/**
39
* Persist option types for store configuration
40
*/
41
type Persist<State = any> = boolean | PersistenceOptions<State> | PersistenceOptions<State>[];
42
```
43
44
**Usage Examples:**
45
46
```typescript
47
import { defineStore } from 'pinia';
48
49
// Simple boolean persistence
50
export const useSimpleStore = defineStore('simple', {
51
state: () => ({ count: 0 }),
52
persist: true,
53
});
54
55
// Configured persistence
56
export const useConfiguredStore = defineStore('configured', {
57
state: () => ({
58
user: { name: 'John', email: 'john@example.com' },
59
settings: { theme: 'dark', notifications: true },
60
tempData: 'not persisted',
61
}),
62
persist: {
63
key: 'user-store',
64
storage: sessionStorage,
65
pick: ['user', 'settings'], // Only persist these fields
66
},
67
});
68
69
// Multiple persistence configurations
70
export const useMultiStore = defineStore('multi', {
71
state: () => ({
72
localData: 'saved locally',
73
sessionData: 'saved in session',
74
tempData: 'not saved',
75
}),
76
persist: [
77
{
78
key: 'local-data',
79
storage: localStorage,
80
pick: ['localData'],
81
},
82
{
83
key: 'session-data',
84
storage: sessionStorage,
85
pick: ['sessionData'],
86
},
87
],
88
});
89
```
90
91
### Store Hydration and Persistence Methods
92
93
Stores with persistence enabled automatically receive additional methods for manual hydration and persistence control.
94
95
```typescript { .api }
96
/**
97
* Additional methods added to persisted stores
98
*/
99
interface PiniaCustomProperties {
100
/** Manually hydrate store from configured storage */
101
$hydrate: (opts?: { runHooks?: boolean }) => void;
102
/** Manually persist store to configured storage */
103
$persist: () => void;
104
}
105
```
106
107
**Usage Examples:**
108
109
```typescript
110
const store = useMyStore();
111
112
// Manual hydration (useful for conditional loading)
113
store.$hydrate();
114
115
// Manual hydration without hooks
116
store.$hydrate({ runHooks: false });
117
118
// Manual persistence (useful for explicit save points)
119
store.$persist();
120
```
121
122
## Configuration Options
123
124
### Key Option
125
126
Custom storage key for the store, overriding the default store ID.
127
128
```typescript { .api }
129
interface PersistenceOptions {
130
key?: string;
131
}
132
```
133
134
**Usage Example:**
135
136
```typescript
137
export const useStore = defineStore('internal-store-id', {
138
state: () => ({ data: [] }),
139
persist: {
140
key: 'user-friendly-key', // Stored as 'user-friendly-key' instead of 'internal-store-id'
141
},
142
});
143
```
144
145
### Storage Selection
146
147
Choose storage backend for this specific store.
148
149
```typescript { .api }
150
interface PersistenceOptions {
151
storage?: StorageLike;
152
}
153
```
154
155
**Usage Examples:**
156
157
```typescript
158
// Use sessionStorage
159
persist: {
160
storage: sessionStorage,
161
}
162
163
// Custom storage
164
persist: {
165
storage: {
166
getItem: (key) => indexedDB.getItem(key),
167
setItem: (key, value) => indexedDB.setItem(key, value),
168
},
169
}
170
```
171
172
### State Filtering
173
174
Control which parts of the state are persisted using pick/omit patterns.
175
176
```typescript { .api }
177
interface PersistenceOptions<State> {
178
/** Include only these paths */
179
pick?: Path<State>[] | string[];
180
/** Exclude these paths */
181
omit?: Path<State>[] | string[];
182
}
183
```
184
185
**Usage Examples:**
186
187
```typescript
188
export const useUserStore = defineStore('user', {
189
state: () => ({
190
profile: {
191
name: 'John',
192
email: 'john@example.com',
193
preferences: {
194
theme: 'dark',
195
notifications: true,
196
},
197
},
198
session: {
199
token: 'secret',
200
expires: Date.now(),
201
},
202
tempData: {},
203
}),
204
persist: {
205
// Only persist user profile and preferences
206
pick: ['profile.name', 'profile.email', 'profile.preferences'],
207
208
// Alternative: exclude sensitive data
209
// omit: ['session.token', 'tempData'],
210
},
211
});
212
```
213
214
### Lifecycle Hooks
215
216
Custom hooks that run before and after state hydration from storage.
217
218
```typescript { .api }
219
interface PersistenceOptions {
220
beforeHydrate?: (context: PiniaPluginContext) => void;
221
afterHydrate?: (context: PiniaPluginContext) => void;
222
}
223
```
224
225
**Usage Examples:**
226
227
```typescript
228
export const useStore = defineStore('store', {
229
state: () => ({ version: '1.0', data: [] }),
230
persist: {
231
beforeHydrate: (context) => {
232
console.log('About to hydrate store:', context.store.$id);
233
},
234
afterHydrate: (context) => {
235
// Migrate data if needed
236
const store = context.store;
237
if (store.version !== '1.0') {
238
// Perform migration logic
239
store.version = '1.0';
240
}
241
},
242
},
243
});
244
```
245
246
### Serialization
247
248
Custom serialization for this store, overriding global serializer.
249
250
```typescript { .api }
251
interface PersistenceOptions {
252
serializer?: Serializer;
253
}
254
255
interface Serializer {
256
serialize: (data: any) => string;
257
deserialize: (data: string) => any;
258
}
259
```
260
261
**Usage Example:**
262
263
```typescript
264
export const useStore = defineStore('store', {
265
state: () => ({ sensitiveData: 'secret' }),
266
persist: {
267
serializer: {
268
serialize: (data) => btoa(JSON.stringify(data)), // Base64 encode
269
deserialize: (data) => JSON.parse(atob(data)), // Base64 decode
270
},
271
},
272
});
273
```