 Have you ever seen the dreaded service worker can't load its script error? Do you wonder why your caches don't seem to work? Well, I'm Sam Dutton, and I'm gonna show you how to debug service workers in the Chrome Developer Tools. Chrome has really good support for debugging PWAs, so let's take it in one piece at a time. We'll work in the order. You might create a PWA, creating a service worker, making it work offline, and then adding a manifest. We'll also look at debugging your logic and testing push notifications. So we're gonna start with this minimal site and build it into a PWA. The code is simple enough, an index.html file and empty file for the service worker and the usual CSS. Let's start with registering the service worker. We'll also see what happens when the service worker changes. We'll add the code to register a service worker into the site, and if registration fails, this will log the error. Now we can switch to the service worker and add its code. This should look familiar. We're listening for the install and activate events and writing a log message. Make sure to save everything. Now, let's look at what we just did. Notice there's nothing in the console yet, but when I reload the page, you should see two messages in the console. One is the service worker installing and the other is when it activates. If you see an error, check your install code and the service worker for syntax errors. Logs are pretty old school. The Chrome developer tools has some specialized tools for debugging PWAs. This is the applications tab and it's where you'll spend most of your time debugging PWAs. Now, a note of caution. The developer tools are evolving constantly. What do you see when you open them might not look exactly like mine. The applications tab has several sections. Let's start with the service worker inspector. Notice that this section in the middle labeled localhost, each service worker runs in its own origin and scope. All of the service workers appear here. Now, in this case, our source file is serviceworker.js and the service worker is activated and running. The clients list shows all of the open windows or tabs controlled by this service worker. Now, let's see what happens when we update the service worker with new code. When I switch back to the browser, you can see that nothing has changed yet. It's the same console messages as before. Now, I can reload the page. You can see the change in the log messages. The browser saw that the service worker changed and it's being reinstalled. If you look at the service worker inspector, you'll see the old service worker is running and the new one is waiting to take over. Now, normally, you would have to close or reload all of the old service workers windows and tabs, but we have a shortcut. Click on skip waiting to let the new service worker take over from the old one. Now, notice that you no longer have two workers visible and that the new one is active. Now, you can see the log message showing the new service worker is active. Back in the inspector, we can click update on reload so new service workers will take over immediately. Just remember this changes the behavior of your service worker so you should not do QA testing with this enabled. Now, let's see how to pre-cache resources and look at them in the developer tools. We want to cache these files when the service worker installs. Remember that the service worker lives at the root of our site and all of these URLs are relative to the root. Now, we can change the install event listener to cache all of the files. Notice that the log message is gone. We will know when this worked by seeing the files in the cache. Now, I can reload the site. Remember that we have update on reload checked so the new service worker takes effect immediately. I cleared the console in case any error messages pop up. Now, our service worker installed and activated. Let's take a look at the cache it just made. Caches will appear under cache storage. When I click on the apps one cache, I can see all of the items in it. Now, before we go on, make sure your service worker is building its cache. If you don't see these files in the cache, check your code and reload the site until they're ready. You can pop over to the network tab and see the difference between the files loaded by the browser and the ones loaded by the service worker. The initiator column will show you which is which. If needed, you can delete the old cache before reloading. You can do this with a right click on the cache name or you can use the clear storage option to wipe out everything, including your caches and current service worker. We have a service worker and it's creating a cache. Now, we want to make the app work offline. Remember that we need to add a fetch handler to the service worker. This will intercept network requests and serve them from the cache. This code adds a fetch handler that serves cache first with a network fallback. In other words, the app will use its cached files and only go to the network if something is missing. Let's reload the browser and make sure there are no errors. We should confirm there's only one service worker running and it's active. So far, so good. But remember, we're still online. There are several ways to take the site offline, including killing the server. But the easiest way is this offline checkbox. Chrome will block traffic between your app and the server as if it's offline. Notice that the network tab has a caution sign. This indicates that you're offline. I'm going to reload this offline app and watch the network panel. The size column indicates which items came from the service worker. Now, you'll notice that there are failed requests for a new service worker and manifest.json. That's totally fine and expected. We haven't added a manifest yet and the service worker caches its own JS file. So that's enough to give you a basic PWA that works offline. There's just one more piece that you must have and that's the manifest. I'm going to add a pre-written manifest to the project. Use the manifest inspector to check the contents of your manifest file. You can click Add to Home Screen to trigger Chrome's Add prompt. Now, what happens when you need to actually debug something? You may get an error loading the service worker or a runtime error. Let's look at the tools and a couple of the common bugs that you might encounter. There are two ways to set a break point. The lesser-known one is to add a debugger statement to your code. Here, we're adding it to our service worker. When we reload the service worker, it stops in the debugger. Look to the right. We can select this service worker's thread and see its runtime environment. This is the same debugging environment you get for any JavaScript. It works the same on the main thread as it does in a worker. We can resume execution and make sure the new service worker is active. You might find it easier to set a break point in the usual way by clicking in the left margin of the source code. So we've seen most of what you would do in building and debugging a PWA, but I saved one of the most complex things for last, push notifications. There's already a button and code for subscribing to push notifications, but it still needs a push listener. The service worker needs to listen for push events. It then creates a notification object and calls show notification. This notification is wrapped in a promise so we need to call event.wait until to pause until it appears. We have to load the new service worker after making the change. I'm checking the usual places to make sure it loaded. Now I can click to subscribe. Of course, I have to give permission to show notifications. Now I can go back to the service worker inspector and notice there's a place to enter and send a push message. When I click the button, it sends a push message straight to the service worker without needing a server. Success. And thanks for listening. Now that you've seen how to debug service workers in Chrome, try it out on your own projects. See the other videos in this series to learn debugging for other browsers and then come back for more PWA videos.