Progressive Web App (PWA) Features
Relevant source files
The following files were used as context for generating this wiki page:
The Smart Absen application incorporates Progressive Web App (PWA) features to provide a more reliable, engaging, and installable user experience. This allows the web application to behave more like a native app, with key capabilities such as offline access and the ability to be added to a user's home screen.
The PWA implementation is centered around the main attendance page (home.html) and consists of a web app manifest, a service worker for caching, and an offline fallback page. Other pages, such as the admin dashboard or QR authentication page, do not appear to include these PWA features.
Sources: templates/home.html, static/manifest.json, static/sw.js
Web App Manifest
The manifest.json file is the core of the PWA, providing the browser with metadata about the application. This information is used when the app is installed on a user's home screen or desktop.
Sources: static/manifest.json, templates/home.html:16
Manifest Configuration
The manifest defines the application's name, icons, start URL, and display properties.
| Property | Value | Description |
|---|---|---|
name | Kafebasabasi - Sistem Absensi Modern | The full name of the application. |
short_name | Kafebasabasi | The name displayed on the user's home screen. |
start_url | / | The entry point of the application when launched from the home screen. |
display | standalone | Opens the app in its own window, without browser UI. |
background_color | #FDF6E3 | The background color of the splash screen. |
theme_color | #3C2415 | The color of the browser's toolbar. |
description | Sistem Absensi Kafebasabasi dengan teknologi Face Recognition & QR Authentication | A brief description of the application's purpose. |
icons | Array of icon objects | A list of application icons for different screen sizes. |
Sources: static/manifest.json:2-10
Manifest Integration
The manifest is linked in the <head> section of the main attendance page, enabling PWA capabilities for that page.
<!-- templates/home.html -->
<link rel="manifest" href="/static/manifest.json">
Sources: templates/home.html:16
Service Worker
The service worker, located at static/sw.js, is a script that runs in the background, separate from the web page. Its primary role in this project is to enable offline functionality by intercepting network requests and serving cached assets.
Sources: static/sw.js
Caching Strategy
The service worker employs a cache-first, then network, with an offline fallback strategy.
The following diagram illustrates the logic for handling fetch events.
Sources: static/sw.js:18-31
Service Worker Lifecycle
-
Installation (
installevent): When the service worker is first registered, theinstallevent is triggered. It opens a cache namedkafebasabasi-v1and populates it with a predefined list of essential assets.
Sources: static/sw.js:2-16 -
Activation: After installation, the service worker activates and takes control of the pages within its scope.
-
Fetch (
fetchevent): Once active, the service worker intercepts all network requests. It first checks if a valid response is in the cache. If so, it returns the cached response immediately. If not, it attempts to fetch the resource from the network. If the network fetch is successful, the response is returned to the page and also stored in the cache for future requests. If the network fetch fails (e.g., the user is offline), the service worker returns theoffline.htmlpage as a fallback.
Sources: static/sw.js:18-31
Cached Assets
The service worker is configured to pre-cache a list of essential URLs upon installation to ensure the core application shell is available offline.
// static/sw.js
const CACHE_NAME = 'kafebasabasi-v1';
const urlsToCache = [
'/',
'/static/css/modern-ui.css',
'/static/js/attendance-optimized.js',
'/static/manifest.json',
'/offline.html'
];
Sources: static/sw.js:2-8
PWA Integration and Installability
The PWA features are integrated into the main application page, templates/home.html, to provide an "installable" experience.
Custom Install Prompt
The application listens for the beforeinstallprompt event, which allows it to trigger the PWA installation prompt programmatically rather than relying on the default browser prompt. This enables a more integrated user experience, such as showing a custom "Install App" button.
The following diagram shows the sequence for the custom installation flow.
This logic is implemented in templates/home.html.
// templates/home.html
let deferredPrompt;
window.addEventListener('beforeinstallprompt', (e) => {
e.preventDefault();
deferredPrompt = e;
// Show install button
const installButton = document.createElement('button');
installButton.className = 'btn btn-outline-light btn-sm position-fixed';
installButton.style.cssText = 'top: 10px; left: 10px; z-index: 1060;';
installButton.innerHTML = '<i class="bi bi-download me-1"></i> Install App';
installButton.onclick = async () => {
if (deferredPrompt) {
deferredPrompt.prompt();
const result = await deferredPrompt.userChoice;
if (result.outcome === 'accepted') {
installButton.remove();
}
deferredPrompt = null;
}
};
document.body.appendChild(installButton);
});
Sources: templates/home_html:1420-1449
Service Worker Registration
For the service worker to function, it must be registered by the application. However, the script to register sw.js (navigator.serviceWorker.register('/static/sw.js')) is not present in templates/home.html or any other provided source files. This indicates that the PWA's offline capabilities are currently not active, and this is a necessary step for full PWA functionality.
Offline Experience
When the service worker is correctly registered, it provides a seamless offline experience. If a user tries to access a page that is not in the cache while they are offline, the service worker intercepts the failed network request and serves a fallback page.
The designated offline fallback page is templates/offline.html. This file is explicitly listed in the service worker's cache and is returned in the catch block of a failed fetch request.
Sources: static/sw.js:29, templates/offline.html