 Hello, I'm Jeff, a member of Google's Web DevRel team. I spend my time building Workbox, a set of production ready libraries that can provide the service worker for your next progressive web app. For this video, we're going to start with a basic online-only web app and walk through the steps required to add a Workbox-powered service worker that will allow it to work offline. The sample app we're starting with consists of an HTML, JavaScript, and CSS file. It makes a call to an API to retrieve a random word and displays it on the page. While this example may include fewer moving parts and frameworks than your own web app, the concepts we're covering here should be generally applicable. First, let's take a look at the traffic in the network panel of Chrome's DevTools when we reload our web app. You'll see requests for the HTML, JavaScript, and CSS files, as well as a request for the cross-origin random word API. We can simulate a loss of network connectivity from the network panel. With this selected, let's try reloading the web app. As you can see, nothing loads. This isn't surprising, as web apps aren't offline capable by default. Let's start the process of adding a service worker to our web app. A properly written service worker can use a combination of the network and cache storage to give us a web app that works in all network conditions. We'll be moving quickly in this video, but if you want to read more about service workers and Workbox, check out workboxjs.org. First, let's add one of the Workbox libraries for a project from NPM using the following command. Next, let's create our sw.ts file, which will contain the code that controls how our service worker behaves. I'm using a .ts extension here, because I'll be writing our service worker code in TypeScript, which Workbox fully supports. In order to use Workbox in your service worker, you first need to import the interfaces that you want to use. Here, we're importing the pre-caching route method from the Workbox pre-caching library we just installed from NPM. Pre-caching route takes in an array describing which URLs we'd like cached, along with revision information to keep track of whether what's already cached is up to date. We call this array the pre-cache manifest. A hard-coded list of URLs and revisions would be difficult to maintain, especially if our web app grew in size. We had more assets to pre-cache. So instead of a hard-coded list, we provide a placeholder, self.__wb__manifest. This special symbol is automatically detected by Workbox's build tools and will be replaced with an up-to-date pre-cache manifest during your build process. But wait, you might be saying, what if I don't already have a build process? That's the case with our web app right now. And I'll walk you through the steps of creating a build script with MPM and running Workbox as part of it. The first step in our build process is going to involve ESBuild. It's a fantastic tool that could take our current TypeScript code, using module code from MPM, and produce a fully bundled JavaScript file suitable for running in the browser as our service worker. We can install ESBuild by running following command. And then we can add a new build script to our project's package JSON to run ESBuild. Now, if we run the following command, we'll see a new sw.js file created, containing JavaScript code for the Workbox runtime libraries we've used. But we've still got that self.__wb__manifest symbol in our script. We need to replace that with a pre-cache manifest for our project. First, let's add one of the Workbox build tools for our project by running the following. Next, we'll run this command. This kicks off a series of questions that will configure which types of assets in our project are added to the pre-cache manifest and which file it injects its manifest into. We want to pre-cache our HTML, JS, and CSS files. And we want to write the pre-cache manifest into the same sw.js file after the build. Finally, we can modify our current build script so that it runs workbox-cli in inject manifest mode right after ESBuild. The configuration we just created via the wizard will automatically be used. With that modification in place, let's build again. The newly updated sw.js file now includes all of the Workbox library code we need, but also a pre-cache manifest containing the URL's and version information for all the assets we want pre-cached. Now that we have a service worker file configured for pre-caching, we need to tell our web app to use it. We could do this by adding the following code to our app.js. This code runs after all of the assets requested by our page have loaded and if service workers are supported in the current browser. And it tells our web app to register the URL for the file we just created. Now the next time we visit our web app, we should see the service worker registered in the applications panel of DevTools. And if we go back to simulate a loss of network connectivity via the network panel and then visit our site again, you can see that all of our HTML, JS, and CSS load successfully. Unfortunately, that's not enough for full offline functionality since our web app needs to be able to make an API call to a service outside of our control. Pre-caching only works for local files, which we're able to obtain information about at build time. We'll need to use what's called a runtime caching strategy to provide a meaningful API response when we're offline. There are a number of runtime caching strategies to choose from, and picking the right one is a trade-off between freshness and speed. Responding with a cached response immediately is usually faster than going to the network, but showing the same cached response multiple times isn't a great experience for many APIs. In this case, we're going to go with a strategy that will attempt to get a response from the network first. The latest valid network response will automatically be stored in a local cache. And if the network request fails because we're offline, that previously cached response will automatically be used. To implement this using Workbox, we'll need to install two more modules, Workbox-Routing and Workbox-Strategies. With these modules installed, we could edit our service worker code to add in a runtime caching route, which will match our API requests and which will apply a network-first strategy to them. This route checks the origin of the URL being requested, and if it corresponds to our API server, applies the network-first strategy using a cache named API-Responses. With the additional code in place, we need to rebuild our service worker file. Now let's try visiting our web app again. Each time we navigate to our web app, the browser automatically checks for an update to our current service worker file. When there's a new version detected, it goes through the install step and hangs out in the waiting step until all open tabs using the previous service worker are closed. If we close the current tab and then revisit it, our updated service worker will be in control and our runtime caching route will save data to the API-Responses cache. And finally, if we emulate being offline one more time in the network panel, you'll see that everything loads as expected and the pre-cached HTML, JS, and CSS, as well as the previously cached API response will all be available. We just went through all the steps required to add offline capabilities to a web app using a combination of pre-cache and runtime caching, all by writing TypeScript code that used Workbox. Workbox offers many more caching strategies, as well as build tools that can generate some of this handwritten code automatically. Check out the documentation at WorkboxJS.org to learn more about how to further customize Workbox for your web app's needs. Also, check out the links in the description for more resources, as well as a link to the sample project.