DEV Community

Cover image for Building Offline-Ready Webpage with Service Worker and Cache Storage
Naimur Rahman
Naimur Rahman

Posted on • Edited on

Building Offline-Ready Webpage with Service Worker and Cache Storage

Why We Need Offline Web Pages

Sometimes, our internet connection isn't reliable or completely absent. In those moments, we still want to use websites and apps. This is where offline web pages come in handy. They allow us to access content even when we're not online.

Introducing Service Workers and Cache Storage

Service Workers are like web helpers. It work behind the scenes to make offline web pages possible. It can save website stuff (like pictures, fonts and other assets) on our device so we can see them even without the internet. It also control what our web page does when it's online.

Cache Storage is like a storage room for web things. It keeps all the website stuff we might need, organised neatly. Service Workers can go there and grab what's needed for page to load offline. So, when we're not online, we still get to see and use web pages.

Let's explore how to make a webpage available offline by doing some simple coding. We'll save an HTML file and an image so that users can still see them, even when they are not connected to the internet.

Step 1: Getting Started
First, Let's create a folder for our project and put main HTML file index.html and the image we want to use cat.jpeg inside it.

Step 2: Registering the Service Worker
Now, let's register the Service Worker in index.html file. Place the following code:



<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <h1>Hi There!</h1>

    <img src="./cat.jpeg" width="300" height="300" />

    <script>
      async function registerServiceWorker() {
        if ("serviceWorker" in navigator) {
          try {
            const registration = await navigator.serviceWorker.register(
              "sw.js"
            );
            console.log(
              "Service Worker registered with scope:",
              registration.scope
            );
          } catch (error) {
            console.error("Service Worker registration failed:", error);
          }
        }
      }

      registerServiceWorker();
    </script>
  </body>
</html>



Enter fullscreen mode Exit fullscreen mode

In this code we check if the browser supports Service Workers.

Step 3: Writing the Service Worker Code
Now, let's create a JavaScript file called sw.js in project folder. This file will contain the code for Service Worker.



const cacheName = "offline-cache-v1";
const cacheUrls = ["index.html", "cat.jpeg"];

// Installing the Service Worker
self.addEventListener("install", async (event) => {
  try {
    const cache = await caches.open(cacheName);
    await cache.addAll(cacheUrls);
  } catch (error) {
    console.error("Service Worker installation failed:", error);
  }
});

// Fetching resources
self.addEventListener("fetch", (event) => {
  event.respondWith(
    (async () => {
      const cache = await caches.open(cacheName);

      try {
        const cachedResponse = await cache.match(event.request);
        if (cachedResponse) {
          console.log("cachedResponse: ", event.request.url);
          return cachedResponse;
        }

        const fetchResponse = await fetch(event.request);
        if (fetchResponse) {
          console.log("fetchResponse: ", event.request.url);
          await cache.put(event.request, fetchResponse.clone());
          return fetchResponse;
        }
      } catch (error) {
        console.log("Fetch failed: ", error);
        const cachedResponse = await cache.match("index.html");
        return cachedResponse;
      }
    })()
  );
});



Enter fullscreen mode Exit fullscreen mode

THere's what's happening in the code:

  • We give a name to our cache (cacheName) and list the URLs (cacheUrls) we want to store for offline use.
  • In the "install" part, we prepare our cache and add the URLs to it.
  • We open the cache and attempt to match the request with the cached responses.
  • If a cached response is found, it's returned. If not, we fetch the resource from the network, cache it for future use, and return the network response.
  • In case of any errors during the fetch process, we handle it by returning a cached version of "index.html" to ensure the user still sees something.

Step 4: Testing our Offline-Friendly webpage
To check if the page works offline:

  • Open the page while the device is online to make sure it loads correctly, including the image.
  • Disconnect from the internet (turn off Wi-Fi or unplug network cable).
  • Reload the page. We should still see the page, including the image, even though there's no internet.

We can also test from the chrome browser, here's the steps:

  • Open the page while the device is online
  • Open devtools in chrome browser and go to the Application tab
  • Click on Service Workers from the sidebar and check the Offline option
  • Reload the page and we can see the contents loading offline

Cate image

We've now created a webpage that can work offline using Service Workers. This technique can be expanded to store more things and make websites robust even when there's no internet.

Full Code 👉 https://github.com/nsourov/offline-web-page

Top comments (4)

Collapse
 
mhasan profile image
Mahmudul Hasan

Great article Naim Vai

Collapse
 
timam profile image
Al-Amin Talukdar

Thanks for revealing secrets of chrome dinosaur game.

Collapse
 
naimur profile image
Naimur Rahman

Yeah, you will miss this game if you implement offline supported page haha

Collapse
 
grabbi96 profile image
grabbi96

Great Bro