 This is an example of an e-commerce site with multiple kinds of data. In this case, there are images and numeric data as well as HTML and CSS resources and probably JavaScript as well. The question here is which data should go where? The general rule is that resources addressed through a URL will be stored in the cache, dynamic resources will be stored in an indexed DB database. For example, AppShell resources, images and style sheets should be stored in the cache. Dynamic JSON data should be stored in indexed DB. Start by storing data locally. Here we're using the cache API and the indexed DB API, also known as IDB. Let's look at storing JSON data with IDB. So, what does IDB look like? It does not look like a conventional SQL table. IDB data is stored as key value pairs in object stores. A single IDB database can have multiple object stores. This could be a clothing object store inside a products database. Now the activate event is a good place to create an IDB database. Point one, you don't want to create it more often than needed for efficiency's sake. And point two, doing that during installation could cause issues with the existing service worker. Note that event.WaitIntel ensures that the service worker does not terminate preemptively during async actions. Here we create an IDB products database. It is version one. Inside the products database we create a clothing object store. This will hold all of the clothing objects. The clothing object store has a key path of ID. Now this means that the objects in this store will be organized and accessed by the ID property of the clothing objects. Note that we're using Jake Archibald's indexed DB promised library to enable promise syntax with IDB. So let's look at storing resources with the cache API. Now a common pattern is to cache assets on service worker installation. Note that event.WaitIntel ensures that the service worker does not terminate preemptively during async actions, like we've said. In this example we create a cache v1 cache and store static assets, that's HTML, CSS, JavaScript, images and so on, with the cache API. Now we can get data from IDB instead of the network. Here we open the products database and create a new transaction on the clothing store of read-only type. We don't need to write data. We can then access the store and retrieve all of the items. These items can then be used to update the UI or whatever is needed. Just a word on transactions. These are a wrapper around an operation or group of operations to ensure database integrity. If one of the actions within a transaction fails, none of them are applied and the database returns to the state it was in before the transaction began. All read or write operations in indexed DB must be part of a transaction. This allows for atomic read modifier write operations without worrying about other threads acting on the database at the same time. Now we can also get resources like HTML, CSS, JavaScript and images from the cache instead of the network. Here we add a fetch listener to the service worker. When a fetch is made for a resource, we try to find the resource in the cache and return it. However, if it isn't in the cache, we still want to go to the network for it. There are plenty of resources to help you get started. For links, take a look at the materials that accompany this video. But first, one more thing. What can we do about actions that a user takes when they're offline? For example, purchasing a product. We can record them in IDB. It's possible to record actions a user takes while offline. In this example, a user is trying to make an item purchase via HTTP request, which will fail if offline. If the purchase fails, the catch block will execute. This is where we can store the item or user action in IDB. How do we use this once connectivity returns? Well, once connectivity returns, the recorded items or actions in IDB can be retrieved and sent. If the requests are successful, the corresponding item action can be deleted from the IDB records.