 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 going to show you how to debug service workers in Safari. We'll work in the order that you might create a PWA, creating a service worker, making it work offline, and debugging the code. Note that we're recording this using the first release of Safari that supports service workers and expect the debugger will change significantly in the future. We're going to start with this minimal site and build it into a PWA. The code is simple enough, an index.html file, an empty file for the service worker, and the usual CSS. So 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. 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 you save everything. Let's look at what we just did. Now notice that there's nothing in the console. Service workers have their own debugging window in the web inspector. And here are the logs we expected. 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. So 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. Look at the console log. The browser saw that the service worker changed and it's being reinstalled. Notice that it hasn't been activated yet. The old service worker is hanging on until the next reload. Instead of reloading everything, you can run some code to unregister it. Remember that you can run JavaScript code in the console. This code snippet unregisters all of the current service workers under the current origin. That lets the pending ones take over. You can see the log messages showing the new service worker is active. Another way to do this is to call skip waiting in your install handler. This makes the new service worker become active immediately. But be careful if this worker makes significant changes to the cache, it may cause problems for older clients that are still running. You need to consider the effects of an immediate takeover before you use this. If you make this change and reload the page, now the worker installs and activates displacing the old worker. So 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'll know when this worked by seeing the files in the cache. Now I can reload the site. The call to skip waiting during install makes the new service worker take effect immediately. I cleared the console in case any error messages pop up. Our service worker installed and activated. Let's take a look at the cache it just made. We can confirm that our resources were cached by running some code in the console. This code logs all of our cache keys which represent the request objects stored there. Here's the list of cached objects. It's what we expected. 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. Sometimes you need to clear a cache while debugging. You can do that through the console. Then we can confirm by rerunning our cache logging code. 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. The network panel confirms we're serving the cached files via the service worker. So far, so good. Now we can see if we work offline. We're going to take the site offline by killing the server. I'm going to reload this offline app. Watch the network panel. It confirms which items came from the service worker. That's enough to give you a basic PWA that works offline. Now what happens when you need to actually debug something? Well, let's look at the debugging tools. Just like regular JavaScript, service workers are supported by the debugger. Just remember to use the one in the service worker inspector and not the one for your main window. Here you can do all the usual debugging you would expect, setting break points, step-by-step execution, inspecting variables, and so on. You can set a break point in the usual way by clicking in the left margin of the source code, or if you prefer, insert a debugger statement right into your code. Of course, the usual resume and step commands work here as well. So thanks for listening. Now that you've seen how to debug service workers in Safari, 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.