0
# Global Configuration
1
2
The `SWRConfig` component provides global configuration for all SWR hooks within its scope, enabling centralized management of fetchers, error handling, and other options.
3
4
## Capabilities
5
6
### SWRConfig Component
7
8
Provider component for configuring SWR behavior globally across the application.
9
10
```typescript { .api }
11
/**
12
* Provider component for global SWR configuration
13
* @param props.value - Partial configuration object to apply globally
14
* @param props.children - Child components that will inherit the configuration
15
*/
16
interface SWRConfig {
17
(props: {
18
value?: Partial<SWRConfiguration>;
19
children: React.ReactNode;
20
}): JSX.Element;
21
22
/** Default configuration values */
23
defaultValue: SWRConfiguration;
24
}
25
```
26
27
**Usage Examples:**
28
29
```typescript
30
import { SWRConfig } from "swr";
31
32
// Basic global configuration
33
function App() {
34
return (
35
<SWRConfig
36
value={{
37
fetcher: (url: string) => fetch(url).then(res => res.json()),
38
onError: (error) => {
39
console.error('SWR Error:', error);
40
}
41
}}
42
>
43
<MyComponents />
44
</SWRConfig>
45
);
46
}
47
48
// Advanced configuration with multiple options
49
function App() {
50
return (
51
<SWRConfig
52
value={{
53
fetcher: customFetcher,
54
revalidateOnFocus: false,
55
revalidateOnReconnect: true,
56
errorRetryCount: 3,
57
errorRetryInterval: 1000,
58
onError: handleGlobalError,
59
onSuccess: handleGlobalSuccess,
60
shouldRetryOnError: (error) => error.status >= 500,
61
}}
62
>
63
<Router />
64
</SWRConfig>
65
);
66
}
67
```
68
69
### useSWRConfig Hook
70
71
Hook to access the current SWR configuration and global mutate function.
72
73
```typescript { .api }
74
/**
75
* Hook to access current SWR configuration and global utilities
76
* @returns Object containing cache, mutate function, and current configuration
77
*/
78
function useSWRConfig(): {
79
cache: Cache;
80
mutate: (key?: Key, data?: any, options?: boolean | MutatorOptions) => Promise<any>;
81
[key: string]: any;
82
};
83
```
84
85
**Usage Examples:**
86
87
```typescript
88
import { useSWRConfig } from "swr";
89
90
function MyComponent() {
91
const { mutate, cache } = useSWRConfig();
92
93
// Global cache mutation
94
const handleInvalidateAll = () => {
95
mutate(() => true); // Revalidate all keys
96
};
97
98
// Specific cache mutation
99
const handleUpdateUser = (newUser: User) => {
100
mutate(`/api/users/${newUser.id}`, newUser, false);
101
};
102
103
// Cache inspection (for debugging)
104
const handleLogCache = () => {
105
console.log("Current cache:", cache);
106
};
107
108
return (
109
<div>
110
<button onClick={handleInvalidateAll}>Refresh All Data</button>
111
<button onClick={handleLogCache}>Log Cache</button>
112
</div>
113
);
114
}
115
```
116
117
### Nested Configuration
118
119
SWR configurations can be nested, with inner configurations overriding outer ones.
120
121
```typescript
122
function App() {
123
return (
124
<SWRConfig
125
value={{
126
fetcher: globalFetcher,
127
revalidateOnFocus: false,
128
}}
129
>
130
<Header />
131
132
{/* Admin section with different configuration */}
133
<SWRConfig
134
value={{
135
fetcher: adminFetcher, // Overrides global fetcher
136
revalidateOnFocus: true, // Overrides global setting
137
onError: adminErrorHandler,
138
}}
139
>
140
<AdminPanel />
141
</SWRConfig>
142
143
<MainContent />
144
</SWRConfig>
145
);
146
}
147
```
148
149
### Global Error Handling
150
151
Configure global error handling for all SWR hooks.
152
153
```typescript
154
function App() {
155
return (
156
<SWRConfig
157
value={{
158
onError: (error, key) => {
159
// Global error logging
160
console.error(`Error for key ${key}:`, error);
161
162
// Report to error tracking service
163
errorTracker.captureException(error, { extra: { key } });
164
165
// Show user-friendly error messages
166
if (error.status === 401) {
167
// Redirect to login
168
window.location.href = "/login";
169
} else if (error.status >= 500) {
170
toast.error("Server error. Please try again later.");
171
} else if (error.status === 404) {
172
toast.error("Resource not found.");
173
}
174
},
175
176
onErrorRetry: (error, key, config, revalidate, { retryCount }) => {
177
// Don't retry on 404
178
if (error.status === 404) return;
179
180
// Don't retry on authentication errors
181
if (error.status === 401) return;
182
183
// Only retry up to 3 times
184
if (retryCount >= 3) return;
185
186
// Exponential backoff
187
setTimeout(() => revalidate({ retryCount }), 2 ** retryCount * 1000);
188
}
189
}}
190
>
191
<App />
192
</SWRConfig>
193
);
194
}
195
```
196
197
### Global Success Handling
198
199
Configure global success callbacks for all SWR hooks.
200
201
```typescript
202
function App() {
203
return (
204
<SWRConfig
205
value={{
206
onSuccess: (data, key) => {
207
// Global success logging
208
console.log(`Successfully loaded ${key}`);
209
210
// Analytics tracking
211
analytics.track("data_loaded", { key });
212
213
// Cache warming for related data
214
if (key.includes("/api/user/")) {
215
// Pre-load user's related data
216
const userId = key.split("/").pop();
217
mutate(`/api/user/${userId}/preferences`);
218
}
219
}
220
}}
221
>
222
<App />
223
</SWRConfig>
224
);
225
}
226
```
227
228
### Global Fetcher Configuration
229
230
Set up a global fetcher with authentication, error handling, and request configuration.
231
232
```typescript
233
// Global fetcher with authentication and error handling
234
const globalFetcher = async (url: string) => {
235
const token = getAuthToken();
236
237
const response = await fetch(url, {
238
headers: {
239
"Content-Type": "application/json",
240
...(token && { Authorization: `Bearer ${token}` }),
241
},
242
});
243
244
if (!response.ok) {
245
const error = new Error(`HTTP ${response.status}: ${response.statusText}`);
246
(error as any).status = response.status;
247
(error as any).response = response;
248
throw error;
249
}
250
251
return response.json();
252
};
253
254
function App() {
255
return (
256
<SWRConfig value={{ fetcher: globalFetcher }}>
257
<Router />
258
</SWRConfig>
259
);
260
}
261
262
// Advanced fetcher with request interceptors
263
const advancedFetcher = async (url: string | [string, RequestInit]) => {
264
const [actualUrl, options = {}] = Array.isArray(url) ? url : [url, {}];
265
266
// Add default headers
267
const headers = {
268
"Content-Type": "application/json",
269
...options.headers,
270
};
271
272
// Add authentication
273
const token = getAuthToken();
274
if (token) {
275
headers.Authorization = `Bearer ${token}`;
276
}
277
278
// Make request
279
const response = await fetch(actualUrl, {
280
...options,
281
headers,
282
});
283
284
// Handle different response types
285
const contentType = response.headers.get("content-type");
286
287
if (!response.ok) {
288
let errorMessage = `HTTP ${response.status}: ${response.statusText}`;
289
290
// Try to get more specific error from response body
291
try {
292
if (contentType?.includes("application/json")) {
293
const errorData = await response.json();
294
errorMessage = errorData.message || errorMessage;
295
}
296
} catch {}
297
298
const error = new Error(errorMessage);
299
(error as any).status = response.status;
300
throw error;
301
}
302
303
// Return appropriate data format
304
if (contentType?.includes("application/json")) {
305
return response.json();
306
} else if (contentType?.includes("text/")) {
307
return response.text();
308
} else {
309
return response.blob();
310
}
311
};
312
```
313
314
### Performance Configuration
315
316
Configure SWR for optimal performance based on your application needs.
317
318
```typescript
319
function App() {
320
return (
321
<SWRConfig
322
value={{
323
// Reduce revalidation frequency for better performance
324
dedupingInterval: 5000, // 5 seconds
325
focusThrottleInterval: 10000, // 10 seconds
326
327
// Disable revalidation for better perceived performance
328
revalidateOnFocus: false,
329
revalidateOnReconnect: true,
330
331
// Optimize error retry
332
errorRetryCount: 2,
333
errorRetryInterval: 2000,
334
shouldRetryOnError: (error) => {
335
// Only retry on network errors and 5xx responses
336
return !error.status || error.status >= 500;
337
},
338
339
// Keep data fresh but reduce network requests
340
refreshInterval: 60000, // 1 minute polling for critical data
341
refreshWhenHidden: false,
342
refreshWhenOffline: false,
343
344
// Improve loading experience
345
keepPreviousData: true,
346
loadingTimeout: 3000,
347
348
onLoadingSlow: (key) => {
349
console.warn(`Slow loading detected for: ${key}`);
350
// Could show a loading indicator or warning
351
}
352
}}
353
>
354
<App />
355
</SWRConfig>
356
);
357
}
358
```
359
360
### Environment-Specific Configuration
361
362
Configure SWR differently based on environment.
363
364
```typescript
365
const getConfig = () => {
366
const baseConfig = {
367
fetcher: globalFetcher,
368
};
369
370
if (process.env.NODE_ENV === "development") {
371
return {
372
...baseConfig,
373
// More aggressive revalidation in development
374
revalidateOnFocus: true,
375
revalidateOnReconnect: true,
376
// Shorter intervals for testing
377
dedupingInterval: 1000,
378
errorRetryInterval: 500,
379
// Detailed logging
380
onError: (error, key) => {
381
console.group(`SWR Error: ${key}`);
382
console.error(error);
383
console.groupEnd();
384
},
385
onSuccess: (data, key) => {
386
console.log(`SWR Success: ${key}`, data);
387
}
388
};
389
}
390
391
if (process.env.NODE_ENV === "production") {
392
return {
393
...baseConfig,
394
// Conservative revalidation in production
395
revalidateOnFocus: false,
396
revalidateOnReconnect: true,
397
// Longer intervals for better performance
398
dedupingInterval: 10000,
399
errorRetryInterval: 5000,
400
// Error reporting only
401
onError: (error, key) => {
402
errorReporter.captureException(error, { extra: { key } });
403
}
404
};
405
}
406
407
return baseConfig;
408
};
409
410
function App() {
411
return (
412
<SWRConfig value={getConfig()}>
413
<Router />
414
</SWRConfig>
415
);
416
}
417
```
418
419
### Dynamic Configuration
420
421
Update SWR configuration based on application state.
422
423
```typescript
424
function ConfigurableApp() {
425
const [isOnline, setIsOnline] = useState(navigator.onLine);
426
const [userPreferences, setUserPreferences] = useState(null);
427
428
useEffect(() => {
429
const handleOnline = () => setIsOnline(true);
430
const handleOffline = () => setIsOnline(false);
431
432
window.addEventListener("online", handleOnline);
433
window.addEventListener("offline", handleOffline);
434
435
return () => {
436
window.removeEventListener("online", handleOnline);
437
window.removeEventListener("offline", handleOffline);
438
};
439
}, []);
440
441
const swrConfig = useMemo(() => ({
442
fetcher: globalFetcher,
443
444
// Adjust behavior based on connection
445
revalidateOnReconnect: isOnline,
446
refreshWhenOffline: false,
447
errorRetryCount: isOnline ? 3 : 0,
448
449
// Adjust based on user preferences
450
revalidateOnFocus: userPreferences?.autoRefresh ?? true,
451
refreshInterval: userPreferences?.pollInterval ?? 0,
452
453
// Custom pause logic
454
isPaused: () => {
455
// Pause requests when offline or user disabled auto-refresh
456
return !isOnline || userPreferences?.pauseRequests;
457
}
458
}), [isOnline, userPreferences]);
459
460
return (
461
<SWRConfig value={swrConfig}>
462
<App />
463
</SWRConfig>
464
);
465
}
466
```