Progressive Web Apps (PWA)

Workbox Library

20 min Lesson 11 of 30

Introduction to Workbox

Workbox is a set of libraries developed by Google that simplifies common service worker routing and caching patterns. It provides production-ready service worker code that handles the complexities of caching strategies, precaching, and offline functionality.

Why Use Workbox?

Managing service workers manually can be complex and error-prone. Workbox provides:

  • Pre-built caching strategies for common use cases
  • Automatic precaching of assets during build time
  • Flexible routing system for handling different types of requests
  • Plugin architecture for extending functionality
  • Development and production builds with debugging support
  • Integration with popular build tools (webpack, Gulp, npm scripts)
Note: Workbox doesn't replace service workers—it makes writing them easier. You still have full control over your service worker behavior.

Installing Workbox

There are several ways to use Workbox depending on your project setup:

1. Using CDN (Quick Start)

<!-- In your service worker file --> importScripts('https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js'); if (workbox) { console.log('Workbox loaded successfully'); // Your Workbox code here } else { console.log('Workbox failed to load'); }

2. Using npm (Recommended for Production)

npm install workbox-webpack-plugin --save-dev # or npm install workbox-cli --save-dev # or npm install workbox-build --save-dev

3. Using workbox-cli

# Install globally npm install workbox-cli --global # Generate a service worker workbox wizard # Build the service worker workbox generateSW workbox-config.js

Basic Workbox Setup

Here's a simple service worker using Workbox from CDN:

// sw.js importScripts('https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js'); // Enable debug mode during development workbox.setConfig({ debug: true }); // Precache files workbox.precaching.precacheAndRoute([ { url: '/', revision: 'v1' }, { url: '/styles/main.css', revision: 'v1' }, { url: '/scripts/app.js', revision: 'v1' } ]); // Cache images with Cache First strategy workbox.routing.registerRoute( ({ request }) => request.destination === 'image', new workbox.strategies.CacheFirst({ cacheName: 'images-cache', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 50, maxAgeSeconds: 30 * 24 * 60 * 60 // 30 days }) ] }) ); // Cache CSS and JS with Stale While Revalidate workbox.routing.registerRoute( ({ request }) => request.destination === 'style' || request.destination === 'script', new workbox.strategies.StaleWhileRevalidate({ cacheName: 'assets-cache' }) ); // Cache Google Fonts workbox.routing.registerRoute( ({ url }) => url.origin === 'https://fonts.googleapis.com', new workbox.strategies.StaleWhileRevalidate({ cacheName: 'google-fonts-stylesheets' }) ); workbox.routing.registerRoute( ({ url }) => url.origin === 'https://fonts.gstatic.com', new workbox.strategies.CacheFirst({ cacheName: 'google-fonts-webfonts', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 30, maxAgeSeconds: 60 * 60 * 24 * 365 // 1 year }) ] }) );

Workbox Precaching

Precaching downloads and caches assets during the service worker installation phase, ensuring they're available offline immediately.

// Manual precaching with revision hashes workbox.precaching.precacheAndRoute([ { url: '/index.html', revision: 'abc123' }, { url: '/styles.css', revision: 'def456' }, { url: '/app.js', revision: 'ghi789' } ]); // The revision hash helps Workbox know when files have changed // and need to be updated in the cache
Tip: In production, use build tools to automatically generate the precache manifest with correct revision hashes. Manual revisions are error-prone and hard to maintain.

Workbox Routing

Workbox routing lets you define how different types of requests should be handled:

// Match by request destination workbox.routing.registerRoute( ({ request }) => request.destination === 'image', new workbox.strategies.CacheFirst() ); // Match by URL pattern (RegExp) workbox.routing.registerRoute( /\.(?:png|jpg|jpeg|svg|gif)$/, new workbox.strategies.CacheFirst() ); // Match by custom function workbox.routing.registerRoute( ({ url, request }) => { return url.pathname.startsWith('/api/') && request.method === 'GET'; }, new workbox.strategies.NetworkFirst() ); // Match specific origin workbox.routing.registerRoute( ({ url }) => url.origin === 'https://api.example.com', new workbox.strategies.NetworkFirst({ cacheName: 'api-cache', networkTimeoutSeconds: 3 }) );

Workbox Caching Strategies

Workbox provides five built-in caching strategies:

1. Cache First (Cache Falling Back to Network)

workbox.routing.registerRoute( ({ request }) => request.destination === 'image', new workbox.strategies.CacheFirst({ cacheName: 'images', plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 }) ] }) );

Best for: Assets that don't change often (images, fonts, CSS libraries)

2. Network First (Network Falling Back to Cache)

workbox.routing.registerRoute( ({ url }) => url.pathname.startsWith('/api/'), new workbox.strategies.NetworkFirst({ cacheName: 'api-cache', networkTimeoutSeconds: 5, plugins: [ new workbox.expiration.ExpirationPlugin({ maxEntries: 50 }) ] }) );

Best for: API requests, dynamic content that needs to be fresh

3. Stale While Revalidate

workbox.routing.registerRoute( ({ request }) => request.destination === 'script', new workbox.strategies.StaleWhileRevalidate({ cacheName: 'js-cache' }) );

Best for: Assets where it's okay to show a slightly outdated version (JS, CSS)

4. Network Only

workbox.routing.registerRoute( ({ url }) => url.pathname.startsWith('/admin/'), new workbox.strategies.NetworkOnly() );

Best for: Requests that must always be fresh (admin panels, real-time data)

5. Cache Only

workbox.routing.registerRoute( ({ url }) => url.pathname === '/offline.html', new workbox.strategies.CacheOnly() );

Best for: Precached assets that should never hit the network

Using Workbox with webpack

For projects using webpack, the workbox-webpack-plugin integrates seamlessly:

// webpack.config.js const WorkboxPlugin = require('workbox-webpack-plugin'); module.exports = { // ... other webpack config plugins: [ new WorkboxPlugin.GenerateSW({ clientsClaim: true, skipWaiting: true, runtimeCaching: [ { urlPattern: /\.(?:png|jpg|jpeg|svg)$/, handler: 'CacheFirst', options: { cacheName: 'images', expiration: { maxEntries: 60, maxAgeSeconds: 30 * 24 * 60 * 60 } } } ] }) ] };

Using workbox-build in Node Scripts

For custom build processes, workbox-build provides programmatic access:

// build-sw.js const workboxBuild = require('workbox-build'); workboxBuild.generateSW({ globDirectory: 'dist/', globPatterns: [ '**/*.{html,js,css,png,jpg,json}' ], swDest: 'dist/sw.js', runtimeCaching: [ { urlPattern: /^https:\/\/fonts\.googleapis\.com/, handler: 'StaleWhileRevalidate', options: { cacheName: 'google-fonts-stylesheets' } } ] }).then(({ count, size }) => { console.log(`Generated service worker with ${count} files (${size} bytes)`); });
# Run the build script node build-sw.js

Workbox Configuration Options

workbox.setConfig({ debug: true, // Enable debug logging modulePathPrefix: '/custom/path/' // Custom path for Workbox modules }); // Set cache name prefix workbox.core.setCacheNameDetails({ prefix: 'my-app', suffix: 'v1', precache: 'precache', runtime: 'runtime' }); // Skip waiting and claim clients workbox.core.skipWaiting(); workbox.core.clientsClaim();
Exercise:
  1. Create a new service worker using Workbox from CDN
  2. Precache your main HTML, CSS, and JS files
  3. Add a CacheFirst strategy for images with a 30-day expiration
  4. Add a NetworkFirst strategy for API calls with a 5-second timeout
  5. Test your caching by going offline and reloading the page
  6. Check the Cache Storage in DevTools to verify cached assets

Debugging Workbox

// Enable debug mode workbox.setConfig({ debug: true }); // Check which routes are registered console.log('Registered routes:', workbox.routing.routes); // Monitor cache operations self.addEventListener('message', (event) => { if (event.data && event.data.type === 'CACHE_URLS') { caches.keys().then(cacheNames => { console.log('All caches:', cacheNames); }); } });
Warning: Always test your Workbox configuration thoroughly. Incorrect caching strategies can lead to stale content being served indefinitely. Use versioning and cache invalidation strategies appropriately.