grupi

Building Offline Capabilities with Service Workers in PWAs

PWAs with Offline Capabilities

PWAs with Offline Capabilities

In a world that is increasingly connected, where our lives seem to revolve around the internet and the cloud, there’s something remarkably appealing about the idea of going offline. Imagine being able to access crucial information, browse articles, or complete tasks, even when you’re stuck in a subway tunnel with no signal. Or think about the frustration of losing unsaved work when your browser crashes unexpectedly. Just imagine, you’re on a hiking trail, surrounded by breathtaking natural beauty, far away from the distractions of emails, notifications, and social media feeds. Yet, you still have access to a seamless digital experience, even without an active internet connection. That’s what PWAs with offline capabilities can do!

PWAs with Offline Capabilities - IMG1

As a developer or software engineer, you’ve probably encountered situations where maintaining a consistent online presence is challenging or downright impossible. Poor network conditions, limited connectivity, or even intentionally disconnected environments can disrupt the flow of information and hinder user experiences. But how is it possible to overcome these challenges?

How is this possible, you ask? Enter the world of Progressive Web Apps (PWAs) and their heroes, Service Workers. Let’s dive into the process of building offline capabilities with Service Workers of your PWA application. Suppose we are creating a News app and want to add all these offline capabilities to it.

Firstly in the serviceWorker.js file we will name our cache.

const cacheName = 'my-news-app-cache';

The “Offline is the New Online”

Offline doesn’t mean “out of the loop” anymore. Users can explore content, make transactions, and engage with your app as if they were in an online wonderland.

self.addEventListener('fetch', (event) => {
event.respondWith(
fetch(event.request).catch(() => {
return caches.match(event.request);
})
);
});

While this code snippet addresses offline functionality, it does not include caching or updating the cache with new content. If you need caching capabilities, additional code would be required. We’ll cover this in the upcoming points.

The “No Signal? No Problem!”

Service Workers perform their magic by intercepting network requests and allowing your PWA to respond even when there’s no signal. With clever caching techniques, they can store previously accessed content and serve it up instantly, keeping users engaged even in the depths of offline despair.

self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName).then(cache => {
return cache.match(event.request).then(response => {
if (response) {
return response;
}

return fetch(event.request).then(networkResponse => {
if (!networkResponse || networkResponse.status !== 200 ||
networkResponse.type !== 'basic') {
return networkResponse;
}

const clonedResponse = networkResponse.clone();
cache.put(event.request, clonedResponse);

return networkResponse;
});
});
})
);
});

By implementing the service worker to caching functionality, it intercepts fetch events and responds with cached resources if available. If a requested resource is not cached, it fetches it from the network and stores a copy in the cache for future use. This allows the application to serve cached responses when offline and fetch fresh responses when online.

The “Offline, but Never Outdated”

Imagine your user opens your PWA, browses articles, and delves into the depths of your content while sipping coffee at a trendy cafe. Suddenly, their connection drops, leaving them stranded in a sea of offline despair. But fear not! Thanks to Service Workers, your PWA can intelligently cache data, ensuring that the content remains up-to-date even when the internet decides to play hide-and-seek. Say goodbye to stale information and hello to a magically fresh user experience.

self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName).then(cache => {
return fetch(event.request).then(networkResponse => {
if (!networkResponse || networkResponse.status !== 200 ||
networkResponse.type !== 'basic') {
return cache.match(event.request);
}

const clonedResponse = networkResponse.clone();
cache.put(event.request, clonedResponse);

return networkResponse;
}).catch(() => {
return cache.match(event.request);
});
})
);
});

Just like before, the service worker intercepts fetch events and responds with cached resources if available. If the requested resource is not cached, it fetches it from the network and stores a copy in the cache for future use. This code ensures that the news reader application can serve cached responses when offline and fetch fresh responses when online, enhancing the user experience and keeping the content up-to-date.

The “Effortless Offline Experience”

Gone are the days of losing progress due to browser crashes or accidental tab closures. Service Workers can save and synchronize user input, allowing for seamless offline work. Users can confidently compose emails, draft documents, or fill out forms without the fear of losing their valuable work.

const cacheName = 'my-news-app-cache';
const dbName = 'my-news-app-db';
const storeName = 'user-inputs';

self.addEventListener('fetch', event => {
event.respondWith(
caches.open(cacheName).then(cache => {
return cache.match(event.request).then(response => {
if (response) {
return response;
}

return fetch(event.request).then(networkResponse => {
if (networkResponse && networkResponse.status === 200) {
const clonedResponse = networkResponse.clone();
cache.put(event.request, clonedResponse);
}

return networkResponse;
});
});
})
);
});

self.addEventListener('sync', event => {
if (event.tag === 'sync-user-inputs') {
event.waitUntil(syncUserInputs());
}
});

function syncUserInputs() {
return caches.open(cacheName).then(cache => {
return cache.keys().then(keys => {
const requests = keys.filter(key => key.url.includes('/user-inputs/'));

return Promise.all(requests.map(request => {
return cache.match(request).then(response => {
if (response) {
return response.text().then(data => {
return fetch('/sync-user-inputs', {
method: 'POST',
body: data
}).then(() => {
// Remove the synced user input from the cache
return cache.delete(request);
});
});
}
});
}));
});
});
}

This code is an example of how you can incorporate saving and synchronization of user input using IndexedDB. It assumes that the user input data is stored as separate requests within the cache. You would need to adapt and modify the code based on your specific requirements and the structure of your user input data.

This comprehensive code allows for seamless offline work and ensures that user input is saved and synchronized, providing a reliable and uninterrupted user experience.
As a MERN stack developer, I’m thrilled about the offline capabilities that Service Workers bring to PWAs. With Service Workers, our apps can continue working even without an internet connection, saving and synchronizing user input. It’s a game-changer that eliminates the fear of losing progress due to browser crashes or accidental tab closures. Users can access the latest information and stay engaged, whether online or offline.

Let’s harness the power of Service Workers, build PWAs with Offline Capabilities, and create exceptional experiences for our users. Remember to optimize your code and content for offline capabilities, implement caching functionality, and prioritize user experience. Don’t let a flaky internet connection limit your app’s potential. Happy coding!

For more information on Progressive Web Apps (PWAs), you can refer to these articles on devfum.com:

  • “Advantages of Progressive Web Apps (PWAs) Over Native Apps” – Read Here
  • “How to Convert an Existing Website to a Progressive Web App (PWA)?” – Read Here

Leave A Comment

Categories

Our purpose is to build solutions that remove barriers preventing people from doing their best work.

Melbourne, Australia
(Sat - Thursday)
(10am - 05 pm)