or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

client-persistence.mdindex.mdquery-persistence.mdretry-strategies.md

client-persistence.mddocs/

0

# Client-Level Persistence

1

2

Complete query client persistence system that automatically saves and restores entire query cache state. This approach is ideal for maintaining full application state across browser sessions, app restarts, or navigation.

3

4

## Capabilities

5

6

### Persist Query Client

7

8

Main function that combines restoration and subscription for complete persistence lifecycle management.

9

10

```typescript { .api }

11

/**

12

* Restores persisted data to QueryCache and persists further changes

13

* @param props - Configuration options for persistence

14

* @returns Tuple of [unsubscribe function, restore promise]

15

*/

16

function persistQueryClient(

17

props: PersistQueryClientOptions

18

): [() => void, Promise<void>];

19

```

20

21

**Usage Example:**

22

23

```typescript

24

import { QueryClient } from "@tanstack/query-core";

25

import { persistQueryClient } from "@tanstack/query-persist-client-core";

26

27

const queryClient = new QueryClient();

28

29

const persister = {

30

persistClient: async (client) => {

31

localStorage.setItem("app-cache", JSON.stringify(client));

32

},

33

restoreClient: async () => {

34

const stored = localStorage.getItem("app-cache");

35

return stored ? JSON.parse(stored) : undefined;

36

},

37

removeClient: async () => {

38

localStorage.removeItem("app-cache");

39

}

40

};

41

42

// Set up complete persistence

43

const [unsubscribe, restorePromise] = persistQueryClient({

44

queryClient,

45

persister,

46

buster: "app-v2.1",

47

maxAge: 1000 * 60 * 60 * 24, // 24 hours

48

dehydrateOptions: {

49

shouldDehydrateQuery: (query) => query.state.status === 'success'

50

},

51

hydrateOptions: {

52

defaultOptions: {

53

queries: { staleTime: 1000 * 60 * 5 } // 5 minutes

54

}

55

}

56

});

57

58

// Wait for restoration to complete

59

try {

60

await restorePromise;

61

console.log("Cache restored successfully");

62

} catch (error) {

63

console.error("Cache restoration failed:", error);

64

}

65

66

// Clean up when component unmounts or app closes

67

unsubscribe();

68

```

69

70

### Persist Query Client Restore

71

72

Restores persisted data to the QueryCache with validation and error handling.

73

74

```typescript { .api }

75

/**

76

* Restores persisted data to the QueryCache

77

* - data obtained from persister.restoreClient

78

* - data is hydrated using hydrateOptions

79

* If data is expired, busted, empty, or throws, it runs persister.removeClient

80

* @param options - Restoration configuration options

81

*/

82

async function persistQueryClientRestore(

83

options: PersistedQueryClientRestoreOptions

84

): Promise<void>;

85

```

86

87

**Usage Example:**

88

89

```typescript

90

import { persistQueryClientRestore } from "@tanstack/query-persist-client-core";

91

92

// Manual restoration with custom options

93

await persistQueryClientRestore({

94

queryClient,

95

persister,

96

maxAge: 1000 * 60 * 60 * 12, // 12 hours instead of default 24

97

buster: "custom-version",

98

hydrateOptions: {

99

defaultOptions: {

100

queries: {

101

staleTime: 1000 * 60 * 10, // 10 minutes

102

cacheTime: 1000 * 60 * 30 // 30 minutes

103

}

104

}

105

}

106

});

107

```

108

109

### Persist Query Client Save

110

111

Persists current query cache data using the provided persister.

112

113

```typescript { .api }

114

/**

115

* Persists data from the QueryCache

116

* - data dehydrated using dehydrateOptions

117

* - data is persisted using persister.persistClient

118

* @param options - Save configuration options

119

*/

120

async function persistQueryClientSave(

121

options: PersistedQueryClientSaveOptions

122

): Promise<void>;

123

```

124

125

**Usage Example:**

126

127

```typescript

128

import { persistQueryClientSave } from "@tanstack/query-persist-client-core";

129

130

// Manual save with selective dehydration

131

await persistQueryClientSave({

132

queryClient,

133

persister,

134

buster: "manual-save-v1",

135

dehydrateOptions: {

136

shouldDehydrateQuery: (query) => {

137

// Only persist successful queries that aren't stale

138

return query.state.status === 'success' && !query.isStale();

139

},

140

shouldDehydrateMutation: () => false // Don't persist mutations

141

}

142

});

143

```

144

145

### Persist Query Client Subscribe

146

147

Creates a subscription to query and mutation cache changes for automatic persistence.

148

149

```typescript { .api }

150

/**

151

* Subscribe to QueryCache and MutationCache updates (for persisting)

152

* @param props - Subscription configuration options

153

* @returns An unsubscribe function to discontinue monitoring

154

*/

155

function persistQueryClientSubscribe(

156

props: PersistedQueryClientSaveOptions

157

): () => void;

158

```

159

160

**Usage Example:**

161

162

```typescript

163

import { persistQueryClientSubscribe } from "@tanstack/query-persist-client-core";

164

165

// Set up automatic persistence on cache changes

166

const unsubscribe = persistQueryClientSubscribe({

167

queryClient,

168

persister,

169

buster: "auto-persist-v1",

170

dehydrateOptions: {

171

shouldDehydrateQuery: (query) => query.state.status === 'success'

172

}

173

});

174

175

// Later, stop automatic persistence

176

unsubscribe();

177

```

178

179

## Configuration Options

180

181

### PersistedQueryClientRestoreOptions

182

183

```typescript { .api }

184

interface PersistedQueryClientRestoreOptions

185

extends PersistQueryClientRootOptions {

186

/** The max-allowed age of the cache in milliseconds.

187

* If a persisted cache is found that is older than this

188

* time, it will be discarded */

189

maxAge?: number;

190

/** The options passed to the hydrate function */

191

hydrateOptions?: HydrateOptions;

192

}

193

```

194

195

### PersistedQueryClientSaveOptions

196

197

```typescript { .api }

198

interface PersistedQueryClientSaveOptions

199

extends PersistQueryClientRootOptions {

200

/** The options passed to the dehydrate function */

201

dehydrateOptions?: DehydrateOptions;

202

}

203

```

204

205

### PersistQueryClientRootOptions

206

207

```typescript { .api }

208

interface PersistQueryClientRootOptions {

209

/** The QueryClient to persist */

210

queryClient: QueryClient;

211

/** The Persister interface for storing and restoring the cache

212

* to/from a persisted location */

213

persister: Persister;

214

/** A unique string that can be used to forcefully

215

* invalidate existing caches if they do not share the same buster string */

216

buster?: string;

217

}

218

```

219

220

### PersistQueryClientOptions

221

222

```typescript { .api }

223

interface PersistQueryClientOptions

224

extends PersistedQueryClientRestoreOptions,

225

PersistedQueryClientSaveOptions,

226

PersistQueryClientRootOptions {}

227

```

228

229

## Error Handling

230

231

The persistence system includes robust error handling:

232

233

- **Restoration Errors**: If restoration fails, the persisted cache is automatically removed to prevent corruption

234

- **Age Validation**: Caches older than `maxAge` are automatically discarded

235

- **Buster Validation**: Caches with mismatched buster strings are discarded to handle version updates

236

- **Development Warnings**: In development mode, errors and warnings are logged to the console

237

238

All persistence operations are non-blocking and will not crash your application if storage fails.