Offline support is critical for modern web applications, especially when dealing with unreliable or intermittent network connections. It ensures a seamless user experience by enabling apps to work without an internet connection. In this chapter, we will explore how to provide offline support using service workers, specifically in the context of Node.js. We’ll cover how service workers work, caching strategies, synchronization of data, and examples to implement offline-first strategies.
Offline support allows a web application to function even when there is no network connectivity. This involves caching resources (HTML, CSS, JS files, images, etc.) and storing data locally to allow users to continue using the app offline.
A service worker is a script that the browser runs in the background, separate from a web page, enabling features that do not require a web page or user interaction, like caching resources and syncing data. It acts as a proxy between the browser and the network and can intercept network requests to provide offline functionality.
// Registering a service worker in your Node.js app
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
.then((registration) => {
console.log('Service Worker registered with scope: ', registration.scope);
})
.catch((error) => {
console.error('Service Worker registration failed:', error);
});
});
}
Start by creating a simple Node.js application with Express to serve your static files.
const express = require('express');
const app = express();
const path = require('path');
// Serve static files
app.use(express.static(path.join(__dirname, 'public')));
app.get('/', (req, res) => {
res.sendFile(path.join(__dirname, 'public', 'index.html'));
});
app.listen(3000, () => {
console.log('App is running on port 3000');
});
Create a service-worker.js
file in your public
folder.
const CACHE_NAME = 'v1';
const urlsToCache = [
'/',
'/styles.css',
'/script.js',
'/offline.html'
];
// Installing the service worker
self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
.then(cache => {
console.log('Opened cache');
return cache.addAll(urlsToCache);
})
);
});
// Fetching the assets
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
.then(response => {
if (response) {
return response; // return from cache
}
return fetch(event.request); // fetch from network
})
.catch(() => caches.match('/offline.html')) // serve offline page if offline
);
});
You can implement various caching strategies based on your app’s requirements. Here are some common strategies:
self.addEventListener('fetch', event => {
event.respondWith(
fetch(event.request)
.then(response => {
// Save the response in the cache
return caches.open(CACHE_NAME).then(cache => {
cache.put(event.request, response.clone());
return response;
});
})
.catch(() => caches.match(event.request)) // fallback to cache if network fails
);
});
Background sync is a feature that allows you to retry requests when the network is available again. For example, submitting a form when offline can be synced once the connection is restored.
self.addEventListener('sync', event => {
if (event.tag === 'syncFormData') {
event.waitUntil(syncFormData());
}
});
function syncFormData() {
// Logic to sync form data to server
console.log('Form data synced');
}
Service workers can be used to send push notifications to the user, even when they are not actively using the app.
self.addEventListener('push', event => {
const options = {
body: 'New message received!',
icon: '/icon.png'
};
event.waitUntil(
self.registration.showNotification('Push Notification', options)
);
});
Service workers provide powerful capabilities to make your Node.js application work offline, enhancing the user experience. They enable efficient caching strategies, background synchronization, and push notifications, which allow the app to work seamlessly without network connectivity. By following this chapter, you now understand the basics and advanced concepts of offline support in Node.js using service workers. This foundational knowledge will help you implement offline-first strategies in your applications, ensuring better performance, resilience, and user satisfaction. Happy coding !❤️