0
# Plugin & Setup
1
2
Vue plugin for installing TanStack Query with global configuration, dependency injection, and lifecycle management for both Vue 2 and Vue 3 applications.
3
4
## Capabilities
5
6
### VueQueryPlugin
7
8
Main Vue plugin for setting up TanStack Query in your application.
9
10
```typescript { .api }
11
/**
12
* Vue plugin for installing TanStack Query
13
* Provides QueryClient via Vue's dependency injection system
14
*/
15
interface VueQueryPlugin {
16
install(app: any, options?: VueQueryPluginOptions): void;
17
}
18
19
interface VueQueryPluginOptions {
20
queryClient?: QueryClient;
21
queryClientConfig?: QueryClientConfig;
22
queryClientKey?: string;
23
enableDevtoolsV6Plugin?: boolean;
24
clientPersister?: ClientPersister;
25
clientPersisterOnSuccess?: (client: QueryClient) => void;
26
}
27
28
type ClientPersister = (client: QueryClient) => [() => void, Promise<void>];
29
30
interface QueryClientConfig {
31
queryCache?: QueryCache;
32
mutationCache?: MutationCache;
33
defaultOptions?: DefaultOptions;
34
}
35
```
36
37
**Usage Examples:**
38
39
```typescript
40
// Vue 3 setup
41
import { createApp } from 'vue';
42
import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
43
import App from './App.vue';
44
45
const app = createApp(App);
46
47
// Basic setup with default configuration
48
const queryClient = new QueryClient();
49
app.use(VueQueryPlugin, { queryClient });
50
51
// Advanced setup with custom configuration
52
const queryClient = new QueryClient({
53
defaultOptions: {
54
queries: {
55
staleTime: 1000 * 60 * 5, // 5 minutes
56
gcTime: 1000 * 60 * 30, // 30 minutes
57
retry: 3,
58
refetchOnWindowFocus: false,
59
refetchOnReconnect: 'always',
60
},
61
mutations: {
62
retry: 1,
63
throwOnError: true,
64
},
65
},
66
});
67
68
app.use(VueQueryPlugin, {
69
queryClient,
70
enableDevtoolsV6Plugin: true,
71
});
72
73
app.mount('#app');
74
75
// Vue 2 setup with Composition API
76
import Vue from 'vue';
77
import VueCompositionAPI from '@vue/composition-api';
78
import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
79
import App from './App.vue';
80
81
Vue.use(VueCompositionAPI);
82
83
const queryClient = new QueryClient();
84
Vue.use(VueQueryPlugin, { queryClient });
85
86
new Vue({
87
render: h => h(App),
88
}).$mount('#app');
89
90
// Setup with configuration object instead of client instance
91
app.use(VueQueryPlugin, {
92
queryClientConfig: {
93
defaultOptions: {
94
queries: {
95
staleTime: 1000 * 60 * 10,
96
retry: 2,
97
},
98
},
99
},
100
enableDevtoolsV6Plugin: process.env.NODE_ENV === 'development',
101
});
102
103
// Multiple client setup with keys
104
const mainClient = new QueryClient();
105
const analyticsClient = new QueryClient();
106
107
app.use(VueQueryPlugin, {
108
queryClient: mainClient,
109
queryClientKey: 'main'
110
});
111
112
app.use(VueQueryPlugin, {
113
queryClient: analyticsClient,
114
queryClientKey: 'analytics'
115
});
116
117
// Usage in components with multiple clients
118
export default {
119
setup() {
120
const mainClient = useQueryClient('main');
121
const analyticsClient = useQueryClient('analytics');
122
123
// Use different clients for different purposes
124
const { data: userData } = useQuery({
125
queryKey: ['user'],
126
queryFn: fetchUser,
127
}, mainClient);
128
129
const { mutate: trackEvent } = useMutation({
130
mutationFn: trackAnalyticsEvent,
131
}, analyticsClient);
132
133
return { userData, trackEvent };
134
}
135
};
136
```
137
138
### Client Persistence
139
140
Setup for persisting query client state across application restarts.
141
142
```typescript { .api }
143
/**
144
* Client persister function type for state persistence
145
* @param client - QueryClient instance to persist
146
* @returns Tuple of [unmount function, ready promise]
147
*/
148
type ClientPersister = (client: QueryClient) => [() => void, Promise<void>];
149
```
150
151
**Usage Examples:**
152
153
```typescript
154
import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
155
import { persistQueryClient } from '@tanstack/query-persist-client-core';
156
import { createSyncStoragePersister } from '@tanstack/query-sync-storage-persister';
157
158
// Create persister
159
const persister = createSyncStoragePersister({
160
storage: window.localStorage,
161
key: 'vue-query-cache',
162
});
163
164
// Setup client persistence
165
const queryClient = new QueryClient({
166
defaultOptions: {
167
queries: {
168
gcTime: 1000 * 60 * 60 * 24, // 24 hours
169
},
170
},
171
});
172
173
app.use(VueQueryPlugin, {
174
queryClient,
175
clientPersister: (client) => {
176
return persistQueryClient({
177
queryClient: client,
178
persister,
179
maxAge: 1000 * 60 * 60 * 24, // 24 hours
180
});
181
},
182
clientPersisterOnSuccess: (client) => {
183
console.log('Query cache restored from storage');
184
},
185
});
186
187
// Custom persister implementation
188
const customPersister = (client) => {
189
let intervalId;
190
191
// Restore from storage
192
const storedState = localStorage.getItem('query-cache');
193
if (storedState) {
194
const parsedState = JSON.parse(storedState);
195
client.setQueriesData({}, parsedState);
196
}
197
198
// Save to storage periodically
199
intervalId = setInterval(() => {
200
const state = client.getQueriesData({});
201
localStorage.setItem('query-cache', JSON.stringify(state));
202
}, 30000); // Save every 30 seconds
203
204
const unmount = () => {
205
clearInterval(intervalId);
206
};
207
208
const ready = Promise.resolve();
209
210
return [unmount, ready];
211
};
212
213
app.use(VueQueryPlugin, {
214
queryClient,
215
clientPersister: customPersister,
216
});
217
```
218
219
### DevTools Integration
220
221
Setup for Vue DevTools integration to inspect query state.
222
223
```typescript { .api }
224
interface VueQueryPluginOptions {
225
enableDevtoolsV6Plugin?: boolean;
226
}
227
```
228
229
**Usage Examples:**
230
231
```typescript
232
import { VueQueryPlugin, QueryClient } from '@tanstack/vue-query';
233
234
// Enable devtools in development
235
app.use(VueQueryPlugin, {
236
queryClient: new QueryClient(),
237
enableDevtoolsV6Plugin: process.env.NODE_ENV === 'development',
238
});
239
240
// Conditional devtools setup
241
const isDevelopment = import.meta.env.DEV;
242
const enableDevtools = isDevelopment && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;
243
244
app.use(VueQueryPlugin, {
245
queryClient: new QueryClient(),
246
enableDevtoolsV6Plugin: enableDevtools,
247
});
248
```
249
250
### SSR Setup
251
252
Server-side rendering configuration for Nuxt.js and other SSR frameworks.
253
254
**Usage Examples:**
255
256
```typescript
257
// Nuxt 3 plugin setup
258
// plugins/vue-query.client.ts
259
import { VueQueryPlugin, QueryClient, hydrate, dehydrate } from '@tanstack/vue-query';
260
261
export default defineNuxtPlugin((nuxtApp) => {
262
const queryClient = new QueryClient({
263
defaultOptions: {
264
queries: {
265
staleTime: 1000 * 60 * 5,
266
},
267
},
268
});
269
270
// Hydrate on client
271
if (process.client) {
272
const dehydratedState = nuxtApp.ssrContext?.nuxt?.data?.vueQueryState;
273
if (dehydratedState) {
274
hydrate(queryClient, dehydratedState);
275
}
276
}
277
278
nuxtApp.vueApp.use(VueQueryPlugin, { queryClient });
279
280
return {
281
provide: {
282
queryClient,
283
},
284
};
285
});
286
287
// Server-side data fetching
288
// server/api/ssr-data.ts
289
export default defineEventHandler(async (event) => {
290
const queryClient = new QueryClient();
291
292
// Prefetch data on server
293
await queryClient.prefetchQuery({
294
queryKey: ['posts'],
295
queryFn: () => $fetch('/api/posts'),
296
});
297
298
// Dehydrate for client
299
const dehydratedState = dehydrate(queryClient);
300
301
return {
302
dehydratedState,
303
};
304
});
305
306
// Vite SSR setup
307
// entry-server.js
308
import { createApp } from 'vue';
309
import { VueQueryPlugin, QueryClient, dehydrate } from '@tanstack/vue-query';
310
import { createSSRApp } from 'vue';
311
312
export async function render(url, manifest) {
313
const app = createSSRApp(App);
314
const queryClient = new QueryClient();
315
316
app.use(VueQueryPlugin, { queryClient });
317
318
// Prefetch critical data
319
await queryClient.prefetchQuery({
320
queryKey: ['user'],
321
queryFn: fetchCurrentUser,
322
});
323
324
const html = await renderToString(app);
325
const state = dehydrate(queryClient);
326
327
return { html, state };
328
}
329
330
// entry-client.js
331
import { createApp } from 'vue';
332
import { VueQueryPlugin, QueryClient, hydrate } from '@tanstack/vue-query';
333
334
const app = createApp(App);
335
const queryClient = new QueryClient();
336
337
// Hydrate with server state
338
if (window.__INITIAL_STATE__) {
339
hydrate(queryClient, window.__INITIAL_STATE__.queryState);
340
}
341
342
app.use(VueQueryPlugin, { queryClient });
343
app.mount('#app');
344
```
345
346
## Types
347
348
```typescript { .api }
349
// Plugin configuration
350
interface VueQueryPluginOptions {
351
queryClient?: QueryClient;
352
queryClientConfig?: QueryClientConfig;
353
queryClientKey?: string;
354
enableDevtoolsV6Plugin?: boolean;
355
clientPersister?: ClientPersister;
356
clientPersisterOnSuccess?: (client: QueryClient) => void;
357
}
358
359
// Configuration interfaces
360
interface QueryClientConfig {
361
queryCache?: QueryCache;
362
mutationCache?: MutationCache;
363
defaultOptions?: DefaultOptions;
364
}
365
366
interface DefaultOptions {
367
queries?: QueryObserverOptions & ShallowOption;
368
mutations?: MutationObserverOptions & ShallowOption;
369
hydrate?: HydrateOptions['defaultOptions'];
370
dehydrate?: DehydrateOptions;
371
}
372
373
// Persister types
374
type ClientPersister = (client: QueryClient) => [() => void, Promise<void>];
375
376
// Hydration types
377
interface DehydrateOptions {
378
shouldDehydrateQuery?: (query: Query) => boolean;
379
shouldDehydrateMutation?: (mutation: Mutation) => boolean;
380
}
381
382
interface HydrateOptions {
383
defaultOptions?: DefaultOptions;
384
mutations?: Array<MutationOptions>;
385
queries?: Array<QueryOptions>;
386
}
387
388
interface DehydratedState {
389
mutations: Array<DehydratedMutation>;
390
queries: Array<DehydratedQuery>;
391
}
392
393
interface DehydratedQuery {
394
queryHash: string;
395
queryKey: QueryKey;
396
state: QueryState;
397
}
398
399
interface DehydratedMutation {
400
mutationKey?: MutationKey;
401
state: MutationState;
402
}
403
```