DEV Community

grace Momah
grace Momah

Posted on

Progressive Web Apps (PWAs): Transforming the Web Experience

Introduction

Progressive Web Apps (PWAs) are web applications that use modern web capabilities to deliver an app-like experience to users. They combine the best of web and mobile apps, providing features like offline access, push notifications, and the ability to install the app on a user's home screen.

Key Features of PWAs

  1. Offline Functionality: PWAs use service workers to cache resources and enable offline access.
  2. Push Notifications: PWAs can send push notifications to engage users.
  3. Installability: Users can install PWAs on their devices without going through an app store.
  4. Responsive Design: PWAs are designed to work seamlessly across different devices and screen sizes.

Benefits of PWAs

  • Improved Performance: Faster load times and smoother interactions.
  • Enhanced User Engagement: Higher retention rates due to push notifications and offline access.
  • Cost-Effective Development: One codebase for all platforms.

Example Code for Building a PWA

Let's build a simple PWA from scratch with HTML, CSS, and JavaScript.

1. HTML Structure

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My PWA</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<h1>Welcome to My PWA</h1>
<p>This is a simple Progressive Web App.</p>
<script src="app.js"></script>
</body>
</html>
Enter fullscreen mode Exit fullscreen mode

2. CSS Styling

body {
    font-family: Arial, sans-serif;
    text-align: center;
    margin: 0;
    padding: 0;
    background-color: #f0f0f0;
}

h1 {
    color: #333;
}

p {
    color: #666;
}
Enter fullscreen mode Exit fullscreen mode

3. JavaScript for Service Workers

Create a file named service-worker.js:

const CACHE_NAME = 'my-pwa-cache-v1';
consturlsToCache = [
    '/',
    '/styles.css',
    '/app.js'
];

self.addEventListener('install', event => {
event.waitUntil(
caches.open(CACHE_NAME)
            .then(cache => {
                return cache.addAll(urlsToCache);
            })
    );
});

self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request)
            .then(response => {
                return response || fetch(event.request);
            })
    );
});
Enter fullscreen mode Exit fullscreen mode

4. Registering the Service Worker

Add the following code to app.js:

if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker.register('/service-worker.js')
            .then(registration => {
console.log('ServiceWorker registration successful with scope: ', registration.scope);
            })
            .catch(error => {
console.log('ServiceWorker registration failed: ', error);
            });
    });
}
Enter fullscreen mode Exit fullscreen mode

5. Web App Manifest

Create a file named manifest.json:

{
    "name": "My PWA",
    "short_name": "PWA",
    "start_url": "/",
    "display": "standalone",
    "background_color": "#ffffff",
    "theme_color": "#000000",
    "icons": [
        {
            "src": "icon.png",
            "sizes": "192x192",
: "type": "image/png"
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Adding Push Notifications to Your PWA

Now that we know all about PWAs, let’s understand how to add push notifications. Push notifications allow you to send messages to users even when they are not actively using your app. This can help increase user engagement and retention.

Setting Up Push Notifications

  1. Requesting Notification Permission First, you need to request permission from the user to send notifications. Add the following code to app.js:
if ('Notification' in window &&navigator.serviceWorker) {
Notification.requestPermission(status => {
console.log('Notification permission status:', status);
    });
}
Enter fullscreen mode Exit fullscreen mode
  1. Registering for Push Notifications Next, you need to register for push notifications with a push service. This example uses the Push API:
function subscribeUserToPush() {
navigator.serviceWorker.ready.then(registration => {
constsubscribeOptions = {
userVisibleOnly: true,
applicationServerKey: urlBase64ToUint8Array(
                'YOUR_PUBLIC_VAPID_KEY'
            )
        };

        return registration.pushManager.subscribe(subscribeOptions);
    }).then(pushSubscription => {
console.log('Received PushSubscription:', JSON.stringify(pushSubscription));
        // Send the subscription to your server
    }).catch(error => {
console.error('Error during getSubscription()', error);
    });
}

function urlBase64ToUint8Array(base64String) {
const padding = '='.repeat((4 - base64String.length % 4) % 4);
const base64 = (base64String + padding)
        .replace(/-/g, '+')
        .replace(/_/g, '/');

constrawData = window.atob(base64);
constoutputArray = new Uint8Array(rawData.length);

    for (let i = 0; i<rawData.length; ++i) {
outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
}
Enter fullscreen mode Exit fullscreen mode

Replace 'YOUR_PUBLIC_VAPID_KEY' with your actual public VAPID key.

  1. Handling Push Events in the Service Worker Add the following code to service-worker.js to handle push events:
self.addEventListener('push', event => {
const data = event.data.json();
const options = {
        body: data.body,
        icon: 'icon.png',
        badge: 'badge.png'
    };

event.waitUntil(
self.registration.showNotification(data.title, options)
    );
});
Enter fullscreen mode Exit fullscreen mode
  1. Sending Push Notifications from the Server To send push notifications, you need to send a POST request to the push service with the subscription details. Here's an example using Node.js and the web-push library:
constwebPush = require('web-push');

constvapidKeys = {
publicKey: 'YOUR_PUBLIC_VAPID_KEY',
privateKey: 'YOUR_PRIVATE_VAPID_KEY'
};

webPush.setVapidDetails(
    'mailto:your-email@example.com',
vapidKeys.publicKey,
vapidKeys.privateKey
);

constpushSubscription = {
    endpoint: 'USER_SUBSCRIPTION_ENDPOINT',
    keys: {
auth: 'USER_AUTH_KEY',
        p256dh: 'USER_P256DH_KEY'
    }
};

const payload = JSON.stringify({
    title: 'Hello!',
    body: 'This is a push notification.'
});

webPush.sendNotification(pushSubscription, payload)
    .then(response =>console.log('Push notification sent:', response))
    .catch(error =>console.error('Error sending push notification:', error));
Enter fullscreen mode Exit fullscreen mode

Please replace 'YOUR_PUBLIC_VAPID_KEY', 'YOUR_PRIVATE_VAPID_KEY', 'USER_SUBSCRIPTION_ENDPOINT', 'USER_AUTH_KEY', and 'USER_P256DH_KEY' with your actual values.

Conclusion

By adding push notifications to your PWA, you can keep users engaged and informed about updates or new content. This can help increase user retention and improve the overall user experience. Happy coding!

Top comments (1)

Collapse
 
dev_king_22 profile image
Kingsley Michael

Here are some additional facts about push notifications in PWAs:

  • They can help increase user engagement by keeping users informed of new content or updates even when they're not actively using your app.
  • Push notifications must be timely, precise, and relevant to be effective.
  • Users have control over their notification preferences, which means they can opt-in or opt-out of receiving them.