or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

index.mdnuxt-integration.mdplugin-configuration.mdstore-persistence.md

store-persistence.mddocs/

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

```