0
# Route and Strategy Classes
1
2
Custom route and strategy classes for implementing specific caching behaviors and request handling patterns. These classes provide the building blocks for advanced precaching setups.
3
4
## Capabilities
5
6
### PrecacheRoute Class
7
8
Route subclass that uses PrecacheController for matching and handling requests with full support for precache-specific URL matching options.
9
10
```typescript { .api }
11
/**
12
* Route subclass that uses PrecacheController for matching and handling requests
13
* Extends workbox-routing.Route
14
*/
15
class PrecacheRoute extends Route {
16
/**
17
* Create a new PrecacheRoute instance
18
* @param precacheController - PrecacheController instance for matching and responding
19
* @param options - Route matching options
20
*/
21
constructor(
22
precacheController: PrecacheController,
23
options?: PrecacheRouteOptions
24
);
25
}
26
```
27
28
**Usage Examples:**
29
30
```typescript
31
import { PrecacheController, PrecacheRoute } from "workbox-precaching";
32
import { registerRoute } from "workbox-routing";
33
34
// Create controller and route
35
const controller = new PrecacheController();
36
const precacheRoute = new PrecacheRoute(controller, {
37
directoryIndex: "index.html",
38
cleanURLs: true,
39
ignoreURLParametersMatching: [/^utm_/, /^ref$/]
40
});
41
42
// Register the route
43
registerRoute(precacheRoute);
44
45
// Add assets to precache
46
controller.precache([
47
{ url: "/index.html", revision: "v1.0" },
48
{ url: "/about.html", revision: "v1.1" }
49
]);
50
```
51
52
### PrecacheStrategy Class
53
54
Strategy implementation specifically designed for precaching with built-in plugins and optimizations for serving precached content.
55
56
```typescript { .api }
57
/**
58
* Strategy implementation specifically designed for precaching
59
* Extends workbox-strategies.Strategy
60
*/
61
class PrecacheStrategy extends Strategy {
62
/**
63
* Create a new PrecacheStrategy instance
64
* @param options - Strategy configuration options
65
*/
66
constructor(options?: PrecacheStrategyOptions);
67
68
/** Default plugin for cache response validation */
69
static readonly defaultPrecacheCacheabilityPlugin: WorkboxPlugin;
70
71
/** Plugin for handling redirected responses */
72
static readonly copyRedirectedCacheableResponsesPlugin: WorkboxPlugin;
73
}
74
```
75
76
**Usage Examples:**
77
78
```typescript
79
import { PrecacheStrategy } from "workbox-precaching";
80
import { registerRoute } from "workbox-routing";
81
82
// Basic precache strategy
83
const strategy = new PrecacheStrategy({
84
cacheName: "precache-v1",
85
plugins: [
86
{
87
cacheKeyWillBeUsed: async ({ request, mode }) => {
88
// Custom cache key generation
89
return `${request.url}?v=2024`;
90
}
91
}
92
]
93
});
94
95
// Use with custom route
96
registerRoute(
97
({ request }) => request.destination === 'document',
98
strategy
99
);
100
101
// Access built-in plugins
102
const cacheabilityPlugin = PrecacheStrategy.defaultPrecacheCacheabilityPlugin;
103
const redirectPlugin = PrecacheStrategy.copyRedirectedCacheableResponsesPlugin;
104
```
105
106
## Configuration Types
107
108
```typescript { .api }
109
interface PrecacheRouteOptions {
110
/** Default file for directory requests (default: 'index.html') */
111
directoryIndex?: string;
112
113
/** URL parameters to ignore when matching (default: [/^utm_/, /^fbclid$/]) */
114
ignoreURLParametersMatching?: RegExp[];
115
116
/** Whether to try .html extension for clean URLs (default: true) */
117
cleanURLs?: boolean;
118
119
/** Custom URL manipulation function for generating additional URL variations */
120
urlManipulation?: urlManipulation;
121
}
122
123
interface PrecacheStrategyOptions {
124
/** Cache name (extends StrategyOptions) */
125
cacheName?: string;
126
/** Plugins array (extends StrategyOptions) */
127
plugins?: WorkboxPlugin[];
128
/** Fetch options (extends StrategyOptions) */
129
fetchOptions?: RequestInit;
130
/** Cache match options (extends StrategyOptions) */
131
matchOptions?: CacheQueryOptions;
132
/** Whether to fall back to network when cache lookup fails */
133
fallbackToNetwork?: boolean;
134
}
135
```
136
137
## Error Handling
138
139
The following errors may be thrown by PrecacheStrategy operations:
140
141
- `WorkboxError('missing-precache-entry')` - Thrown when `fallbackToNetwork: false` and no cached response is found
142
- `WorkboxError('bad-precaching-response')` - Thrown during installation if a response cannot be cached properly
143
144
## Advanced Usage Patterns
145
146
### Custom Route with Multiple Controllers
147
148
```typescript
149
import {
150
PrecacheController,
151
PrecacheRoute,
152
PrecacheStrategy
153
} from "workbox-precaching";
154
import { registerRoute } from "workbox-routing";
155
156
// Different controllers for different asset types
157
const shellController = new PrecacheController({
158
cacheName: "app-shell-v1"
159
});
160
161
const resourceController = new PrecacheController({
162
cacheName: "resources-v1"
163
});
164
165
// Custom routes for each controller
166
const shellRoute = new PrecacheRoute(shellController, {
167
directoryIndex: "app.html"
168
});
169
170
const resourceRoute = new PrecacheRoute(resourceController, {
171
cleanURLs: false,
172
ignoreURLParametersMatching: []
173
});
174
175
// Register routes
176
registerRoute(shellRoute);
177
registerRoute(resourceRoute);
178
```
179
180
### Strategy with Custom Plugins
181
182
```typescript
183
import { PrecacheStrategy } from "workbox-precaching";
184
185
const customStrategy = new PrecacheStrategy({
186
cacheName: "enhanced-precache",
187
plugins: [
188
// Use built-in plugins
189
PrecacheStrategy.defaultPrecacheCacheabilityPlugin,
190
PrecacheStrategy.copyRedirectedCacheableResponsesPlugin,
191
192
// Add custom plugin
193
{
194
requestWillFetch: async ({ request }) => {
195
// Add custom headers
196
const modifiedRequest = new Request(request, {
197
headers: {
198
...request.headers,
199
'X-Precache-Version': '1.0'
200
}
201
});
202
return modifiedRequest;
203
},
204
205
cacheDidUpdate: async ({ cacheName, request, oldResponse, newResponse }) => {
206
// Log cache updates
207
console.log(`Cache updated: ${request.url}`);
208
209
// Notify other tabs about updates
210
if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
211
navigator.serviceWorker.controller.postMessage({
212
type: 'CACHE_UPDATED',
213
url: request.url
214
});
215
}
216
}
217
}
218
]
219
});
220
```
221
222
### Route with Custom URL Manipulation
223
224
```typescript
225
import { PrecacheController, PrecacheRoute } from "workbox-precaching";
226
227
const controller = new PrecacheController();
228
229
const route = new PrecacheRoute(controller, {
230
cleanURLs: true,
231
directoryIndex: "index.html",
232
233
// Custom URL manipulation for SPA routing
234
urlManipulation: ({ url }) => {
235
const additionalURLs: URL[] = [];
236
237
// For SPA routes, also try the root index.html
238
if (url.pathname.startsWith('/app/')) {
239
const rootUrl = new URL(url);
240
rootUrl.pathname = '/app/index.html';
241
additionalURLs.push(rootUrl);
242
}
243
244
// Try variations with/without trailing slashes
245
if (url.pathname.endsWith('/')) {
246
const withoutSlash = new URL(url);
247
withoutSlash.pathname = withoutSlash.pathname.slice(0, -1);
248
additionalURLs.push(withoutSlash);
249
} else {
250
const withSlash = new URL(url);
251
withSlash.pathname += '/';
252
additionalURLs.push(withSlash);
253
}
254
255
return additionalURLs;
256
}
257
});
258
```
259
260
### Strategy for Different Asset Types
261
262
```typescript
263
import { PrecacheStrategy } from "workbox-precaching";
264
import { registerRoute } from "workbox-routing";
265
266
// Strategy for HTML documents
267
const documentStrategy = new PrecacheStrategy({
268
cacheName: "documents-precache",
269
plugins: [
270
{
271
cacheWillUpdate: async ({ response }) => {
272
// Only cache successful HTML responses
273
return response.status === 200 &&
274
response.headers.get('content-type')?.includes('text/html')
275
? response
276
: null;
277
}
278
}
279
]
280
});
281
282
// Strategy for static assets
283
const assetStrategy = new PrecacheStrategy({
284
cacheName: "assets-precache",
285
plugins: [
286
{
287
cacheWillUpdate: async ({ response }) => {
288
// Cache assets for longer periods
289
return response.status === 200 ? response : null;
290
}
291
}
292
]
293
});
294
295
// Register routes with different strategies
296
registerRoute(
297
({ request }) => request.destination === 'document',
298
documentStrategy
299
);
300
301
registerRoute(
302
({ request }) => ['style', 'script', 'image'].includes(request.destination),
303
assetStrategy
304
);
305
```
306
307
## Integration with Routing
308
309
### Complete Setup Example
310
311
```typescript
312
import {
313
PrecacheController,
314
PrecacheRoute,
315
PrecacheStrategy
316
} from "workbox-precaching";
317
import { registerRoute } from "workbox-routing";
318
319
// 1. Create controller
320
const controller = new PrecacheController({
321
cacheName: "my-app-precache-v1"
322
});
323
324
// 2. Create custom strategy
325
const strategy = new PrecacheStrategy({
326
cacheName: "my-app-precache-v1",
327
plugins: [
328
PrecacheStrategy.defaultPrecacheCacheabilityPlugin,
329
{
330
cacheDidUpdate: async ({ cacheName, request }) => {
331
console.log(`Updated ${request.url} in ${cacheName}`);
332
}
333
}
334
]
335
});
336
337
// 3. Create and register route
338
const route = new PrecacheRoute(controller, {
339
directoryIndex: "index.html",
340
cleanURLs: true
341
});
342
343
registerRoute(route);
344
345
// 4. Add assets to precache
346
controller.precache([
347
{ url: "/", revision: "v1.0.0" },
348
{ url: "/about.html", revision: "v1.0.1" },
349
{ url: "/contact.html", revision: "v1.0.0" }
350
]);
351
```