CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-workbox-precaching

This module efficiently precaches assets for Progressive Web Apps and service workers.

Pending
Overview
Eval results
Files

route-strategy.mddocs/

Route and Strategy Classes

Custom route and strategy classes for implementing specific caching behaviors and request handling patterns. These classes provide the building blocks for advanced precaching setups.

Capabilities

PrecacheRoute Class

Route subclass that uses PrecacheController for matching and handling requests with full support for precache-specific URL matching options.

/**
 * Route subclass that uses PrecacheController for matching and handling requests
 * Extends workbox-routing.Route
 */
class PrecacheRoute extends Route {
  /**
   * Create a new PrecacheRoute instance
   * @param precacheController - PrecacheController instance for matching and responding
   * @param options - Route matching options
   */
  constructor(
    precacheController: PrecacheController,
    options?: PrecacheRouteOptions
  );
}

Usage Examples:

import { PrecacheController, PrecacheRoute } from "workbox-precaching";
import { registerRoute } from "workbox-routing";

// Create controller and route
const controller = new PrecacheController();
const precacheRoute = new PrecacheRoute(controller, {
  directoryIndex: "index.html",
  cleanURLs: true,
  ignoreURLParametersMatching: [/^utm_/, /^ref$/]
});

// Register the route
registerRoute(precacheRoute);

// Add assets to precache
controller.precache([
  { url: "/index.html", revision: "v1.0" },
  { url: "/about.html", revision: "v1.1" }
]);

PrecacheStrategy Class

Strategy implementation specifically designed for precaching with built-in plugins and optimizations for serving precached content.

/**
 * Strategy implementation specifically designed for precaching
 * Extends workbox-strategies.Strategy
 */
class PrecacheStrategy extends Strategy {
  /**
   * Create a new PrecacheStrategy instance
   * @param options - Strategy configuration options
   */
  constructor(options?: PrecacheStrategyOptions);

  /** Default plugin for cache response validation */
  static readonly defaultPrecacheCacheabilityPlugin: WorkboxPlugin;
  
  /** Plugin for handling redirected responses */
  static readonly copyRedirectedCacheableResponsesPlugin: WorkboxPlugin;
}

Usage Examples:

import { PrecacheStrategy } from "workbox-precaching";
import { registerRoute } from "workbox-routing";

// Basic precache strategy
const strategy = new PrecacheStrategy({
  cacheName: "precache-v1",
  plugins: [
    {
      cacheKeyWillBeUsed: async ({ request, mode }) => {
        // Custom cache key generation
        return `${request.url}?v=2024`;
      }
    }
  ]
});

// Use with custom route
registerRoute(
  ({ request }) => request.destination === 'document',
  strategy
);

// Access built-in plugins
const cacheabilityPlugin = PrecacheStrategy.defaultPrecacheCacheabilityPlugin;
const redirectPlugin = PrecacheStrategy.copyRedirectedCacheableResponsesPlugin;

Configuration Types

interface PrecacheRouteOptions {
  /** Default file for directory requests (default: 'index.html') */
  directoryIndex?: string;
  
  /** URL parameters to ignore when matching (default: [/^utm_/, /^fbclid$/]) */
  ignoreURLParametersMatching?: RegExp[];
  
  /** Whether to try .html extension for clean URLs (default: true) */
  cleanURLs?: boolean;
  
  /** Custom URL manipulation function for generating additional URL variations */
  urlManipulation?: urlManipulation;
}

interface PrecacheStrategyOptions {
  /** Cache name (extends StrategyOptions) */
  cacheName?: string;
  /** Plugins array (extends StrategyOptions) */
  plugins?: WorkboxPlugin[];
  /** Fetch options (extends StrategyOptions) */
  fetchOptions?: RequestInit;
  /** Cache match options (extends StrategyOptions) */
  matchOptions?: CacheQueryOptions;
  /** Whether to fall back to network when cache lookup fails */
  fallbackToNetwork?: boolean;
}

Error Handling

The following errors may be thrown by PrecacheStrategy operations:

  • WorkboxError('missing-precache-entry') - Thrown when fallbackToNetwork: false and no cached response is found
  • WorkboxError('bad-precaching-response') - Thrown during installation if a response cannot be cached properly

Advanced Usage Patterns

Custom Route with Multiple Controllers

import { 
  PrecacheController, 
  PrecacheRoute,
  PrecacheStrategy 
} from "workbox-precaching";
import { registerRoute } from "workbox-routing";

// Different controllers for different asset types
const shellController = new PrecacheController({
  cacheName: "app-shell-v1"
});

const resourceController = new PrecacheController({
  cacheName: "resources-v1"
});

// Custom routes for each controller
const shellRoute = new PrecacheRoute(shellController, {
  directoryIndex: "app.html"
});

const resourceRoute = new PrecacheRoute(resourceController, {
  cleanURLs: false,
  ignoreURLParametersMatching: []
});

// Register routes
registerRoute(shellRoute);
registerRoute(resourceRoute);

Strategy with Custom Plugins

import { PrecacheStrategy } from "workbox-precaching";

const customStrategy = new PrecacheStrategy({
  cacheName: "enhanced-precache",
  plugins: [
    // Use built-in plugins
    PrecacheStrategy.defaultPrecacheCacheabilityPlugin,
    PrecacheStrategy.copyRedirectedCacheableResponsesPlugin,
    
    // Add custom plugin
    {
      requestWillFetch: async ({ request }) => {
        // Add custom headers
        const modifiedRequest = new Request(request, {
          headers: {
            ...request.headers,
            'X-Precache-Version': '1.0'
          }
        });
        return modifiedRequest;
      },
      
      cacheDidUpdate: async ({ cacheName, request, oldResponse, newResponse }) => {
        // Log cache updates
        console.log(`Cache updated: ${request.url}`);
        
        // Notify other tabs about updates
        if ('serviceWorker' in navigator && navigator.serviceWorker.controller) {
          navigator.serviceWorker.controller.postMessage({
            type: 'CACHE_UPDATED',
            url: request.url
          });
        }
      }
    }
  ]
});

Route with Custom URL Manipulation

import { PrecacheController, PrecacheRoute } from "workbox-precaching";

const controller = new PrecacheController();

const route = new PrecacheRoute(controller, {
  cleanURLs: true,
  directoryIndex: "index.html",
  
  // Custom URL manipulation for SPA routing
  urlManipulation: ({ url }) => {
    const additionalURLs: URL[] = [];
    
    // For SPA routes, also try the root index.html
    if (url.pathname.startsWith('/app/')) {
      const rootUrl = new URL(url);
      rootUrl.pathname = '/app/index.html';
      additionalURLs.push(rootUrl);
    }
    
    // Try variations with/without trailing slashes
    if (url.pathname.endsWith('/')) {
      const withoutSlash = new URL(url);
      withoutSlash.pathname = withoutSlash.pathname.slice(0, -1);
      additionalURLs.push(withoutSlash);
    } else {
      const withSlash = new URL(url);
      withSlash.pathname += '/';
      additionalURLs.push(withSlash);
    }
    
    return additionalURLs;
  }
});

Strategy for Different Asset Types

import { PrecacheStrategy } from "workbox-precaching";
import { registerRoute } from "workbox-routing";

// Strategy for HTML documents
const documentStrategy = new PrecacheStrategy({
  cacheName: "documents-precache",
  plugins: [
    {
      cacheWillUpdate: async ({ response }) => {
        // Only cache successful HTML responses
        return response.status === 200 && 
               response.headers.get('content-type')?.includes('text/html') 
          ? response 
          : null;
      }
    }
  ]
});

// Strategy for static assets
const assetStrategy = new PrecacheStrategy({
  cacheName: "assets-precache",
  plugins: [
    {
      cacheWillUpdate: async ({ response }) => {
        // Cache assets for longer periods
        return response.status === 200 ? response : null;
      }
    }
  ]
});

// Register routes with different strategies
registerRoute(
  ({ request }) => request.destination === 'document',
  documentStrategy
);

registerRoute(
  ({ request }) => ['style', 'script', 'image'].includes(request.destination),
  assetStrategy
);

Integration with Routing

Complete Setup Example

import { 
  PrecacheController, 
  PrecacheRoute, 
  PrecacheStrategy 
} from "workbox-precaching";
import { registerRoute } from "workbox-routing";

// 1. Create controller
const controller = new PrecacheController({
  cacheName: "my-app-precache-v1"
});

// 2. Create custom strategy
const strategy = new PrecacheStrategy({
  cacheName: "my-app-precache-v1",
  plugins: [
    PrecacheStrategy.defaultPrecacheCacheabilityPlugin,
    {
      cacheDidUpdate: async ({ cacheName, request }) => {
        console.log(`Updated ${request.url} in ${cacheName}`);
      }
    }
  ]
});

// 3. Create and register route
const route = new PrecacheRoute(controller, {
  directoryIndex: "index.html",
  cleanURLs: true
});

registerRoute(route);

// 4. Add assets to precache
controller.precache([
  { url: "/", revision: "v1.0.0" },
  { url: "/about.html", revision: "v1.0.1" },
  { url: "/contact.html", revision: "v1.0.0" }
]);

Install with Tessl CLI

npx tessl i tessl/npm-workbox-precaching

docs

advanced-controller.md

index.md

plugins-cleanup.md

route-strategy.md

simple-setup.md

utilities.md

tile.json