Skip to content

Commit d104790

Browse files
authored
Merge pull request #10895 from EnasAbdelrazek/ufc-document-pwa
Document Service worker and PWA updates
2 parents 3684930 + b009075 commit d104790

2 files changed

Lines changed: 145 additions & 3 deletions

File tree

content/en/docs/refguide/mobile/introduction-to-mobile-technologies/progressive-web-app.md renamed to content/en/docs/refguide/mobile/introduction-to-mobile-technologies/progressive-web-app/_index.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Progressive web apps (PWAs) are an evolution of traditional web apps. Overall, P
1313
Progressive web apps have three main characteristics:
1414

1515
* **Installable** – PWAs let you add your app to your user's home screen and start a full screen app. This makes PWAs feel more fully-capable native apps.
16-
* **Reliable** – Using service workers, PWAs can work offline or partially offline. Mendix PWAs can work partially offline (resources like styling, pages, and images are cached) or fully offline (like native mobile apps).
16+
* **Reliable** – Using [service workers](/refguide/mobile/introduction-to-mobile-technologies/pwa-service-worker/), PWAs can work offline or partially offline. Mendix PWAs can work partially offline (resources like styling, pages, and images are cached) or fully offline (like native mobile apps).
1717
* **Capable** – PWAs can leverage several device capabilities like the camera and location, and can offer support for web push notifications. Note that support for features depend on which browser is used.
1818

1919
## Enabling PWA Features
@@ -34,11 +34,11 @@ Within the navigation profiles the following PWA features can be configured:
3434

3535
{{< figure src="/attachments/refguide/mobile/progressive-web-app/settings.png" alt="PWA settings" width="350" class="no-border" >}}
3636

37-
To be able to fully test PWA functionalities, the app needs to be deployed to the cloud. This is because some PWA features are only available over HTTPS protocol. For more information, see [Accessing Device Features](#accessing-device-features) below.
37+
To fully test PWA functionality, the app needs to be deployed to the cloud. This is because some PWA features are only available over HTTPS protocol. For more information, see [Accessing Device Features](#accessing-device-features) below.
3838

3939
### Publishing as a Progressive Web App
4040

41-
When checked and deployed to the cloud, the app registers a [service worker](https://developers.google.com/web/fundamentals/primers/service-workers) that is the basis for PWAs. On offline navigation profiles, this option is always enabled. In online navigation profiles, enabling this option will also give the end-user a custom page when the device has no connection. Where desired, this page can be customized by adding an *offline.html* page to the theme folder (for example, *theme/offline.html*). Note that this page should not load any other resources over the network.
41+
When checked and deployed to the cloud, the app registers a [service worker](/refguide/mobile/introduction-to-mobile-technologies/pwa-service-worker/) that is the basis for PWAs. On offline navigation profiles, this option is always enabled. In online navigation profiles, enabling this option will also give the end-user a custom page when the device has no connection. Where desired, this page can be customized by adding an *offline.html* page to the theme folder (for example, *theme/offline.html*). Note that this page should not load any other resources over the network.
4242

4343
### Allowing "Add to Home Screen" Prompt
4444

@@ -107,6 +107,10 @@ Next to that, it is possible to force a profile by providing the profile name in
107107

108108
When forcing a specific profile on a cloud deployment, it can be necessary to first clear the browser cache.
109109

110+
## Managing PWA Updates
111+
112+
To learn more about the service worker lifecycle and how to detect and handle PWA updates to provide users with the latest version, see [Service Worker and PWA Updates](/refguide/mobile/introduction-to-mobile-technologies/pwa-service-worker/).
113+
110114
## Advanced Settings
111115

112116
See the sections below for information on advanced settings.
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
---
2+
title: "PWA Service Worker"
3+
url: /refguide/mobile/introduction-to-mobile-technologies/pwa-service-worker/
4+
weight: 20
5+
---
6+
7+
## Introduction
8+
9+
A service worker is a specialized type of web worker, essentially a JavaScript file that runs in the background, separate from your main web page. It can control pages within its [scope](#scope), and acts as a proxy between your progressive web app (PWA) and the network.
10+
11+
A service worker's primary role is to intercept network requests made by your PWA and decide whether to fetch resources from the network or serve them from the cache. This interception capability is crucial for providing robust offline experiences, and enables your PWA to function even when the user has no network connectivity.
12+
13+
## Service Worker Scope {#scope}
14+
15+
A service worker’s scope is determined by the location of its JavaScript file on the web server. For example, if a service worker runs on a page located at `/subdir/index.html` and is located at `/subdir/sw.js`, then the service worker's scope is `/subdir/`.
16+
17+
Scope limits which pages are controlled by a service worker, not which requests it can intercept. Once a service worker controls a page, it can intercept any network request that page makes, including requests to cross-origin resources.
18+
19+
## Service Worker Lifecycle
20+
21+
To understand how updates to your Mendix PWA are handled, you need to understand the service worker lifecycle. A service worker goes through several distinct phases:
22+
23+
1. **Registration** — In this step the browser downloads the service worker file. If the code contains syntax errors, registration fails and the service worker is discarded.
24+
2. **Installation** — During this phase, the service worker typically caches static assets your PWA needs to function offline. If all assets are successfully pre-cached, the installation succeeds. If installation fails, the service worker is discarded.
25+
* Once installed:
26+
- It becomes activated immediately if no other service worker is currently controlling the page.
27+
- If there is already an active service worker, the new one will be installed but enters a **Waiting** state. The **Waiting** state, ensures that updates to your application are delivered smoothly and without interrupting your users' current interactions.
28+
3. **Activation** — Once installed, the service worker enters the **Activating** state, and then becomes **Activated**. An **Activated** service worker takes control of pages within its scope (meaning it is ready to intercept requests).
29+
4. **Redundant** — A service worker can become redundant if a new version replaces it, or if it fails to install.
30+
31+
## Waiting for Service Worker Readiness
32+
33+
Mendix recommends waiting until the service worker is ready before performing operations that rely on it, such as interacting with the app while offline.
34+
35+
The browser provides the [ready](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerContainer/ready) property, which returns a **Promise** that resolves when a service worker is active to ensure that the service worker is fully initialized and that precaching of assets is complete so the app can work offline:
36+
37+
```javascript
38+
export async function waitForAppReady() {
39+
if (!('serviceWorker' in navigator)) {
40+
console.warn('service workers are not supported in this browser.');
41+
return;
42+
}
43+
const registration = await navigator.serviceWorker.ready;
44+
45+
console.log('A Service Worker is active:', registration.active);
46+
// At this point, a service worker is active.
47+
// A page reload is necessary to ensure all assets are served by the new service worker and the app is fully offline ready
48+
}
49+
```
50+
51+
## Service Worker Update
52+
53+
When you deploy a new version of your Mendix PWA, a new service worker file is generated with updated caching strategies and assets list.
54+
The browser detects this update and initiates a new lifecycle for the updated service worker.
55+
56+
1. New service worker installation: The new service worker starts to install and cache assets.
57+
2. Waiting state: Once the new service worker is successfully installed, it enters a waiting state. The old service worker remains active and in control of your PWA.
58+
3. Activation of the new service worker: The new service worker will only activate when all instances of your PWA (all open tabs or windows) that are controlled by the old service worker are closed.
59+
60+
## Detecting and Handling Updates in Your PWA
61+
62+
The [ServiceWorkerRegistration](https://developer.mozilla.org/en-US/docs/Web/API/ServiceWorkerRegistration) interface provides properties and methods to monitor its state and detect updates. In Mendix 11.9.0 and above, a Client API [method](https://apidocs.rnd.mendix.com/11/client-mx-api/module-mx-api_pwa.html) is available to skip the waiting phase and immediately activate the new service worker version: `SkipWaiting()`.
63+
64+
You can implement a custom update mechanism to provide a clear notification and an option to update to the latest version of your app in that same notification. This allows them to update the application without closing all tabs or windows:
65+
66+
1. **Listen for service worker updates** — Create a JavaScript Action to listen for service worker updates. This action should run when your application starts up, for example, calling the JavaScript action via nanoflow that triggers by [Events](/appstore/widgets/events/) widget:
67+
68+
```javascript
69+
export async function JS_ListenForPWAUpdates() {
70+
if (!('serviceWorker' in navigator)) {
71+
console.warn('service workers are not supported in this browser.');
72+
return;
73+
}
74+
75+
try {
76+
const registration = await navigator.serviceWorker.getRegistration();
77+
78+
if (registration) {
79+
// Detect when a new service worker update is found
80+
registration.addEventListener('updatefound', () => {
81+
const newWorker = registration.installing;
82+
83+
if (newWorker) {
84+
// Listen for state changes in the new service worker
85+
newWorker.addEventListener('statechange', () => {
86+
// New service worker is installed and ready.
87+
if (newWorker.state === 'installed'){
88+
// The new service worker is waiting because an existing service worker is active
89+
if(navigator.serviceWorker.controller) {
90+
console.log('A new update is available. Notify the user.');
91+
// Show a confirmation dialog or implement your custom update UI
92+
// to notify the user that an update is available
93+
} else {
94+
console.log("Service Worker installed and ready.");
95+
// This is the first time a service worker is installed and activated for this page.
96+
// A page reload is necessary to ensure all assets are served by the new service worker and the app is fully offline ready
97+
}
98+
}
99+
});
100+
}
101+
});
102+
103+
if (registration.waiting) {
104+
console.log('An update is already available and waiting. Notify the user.');
105+
// Show a confirmation dialog or call your custom update flow
106+
// to notify the user that an update is available
107+
}
108+
}
109+
} catch (error) {
110+
console.error('Error setting up service worker update listener:', error);
111+
}
112+
}
113+
```
114+
115+
2. **Create a JavaScript Action to activate the new service worker** — When the user confirms the update, use the Client API `skipWaiting()` to activate the new service worker:
116+
117+
```javascript
118+
import { skipWaiting } from "mx-api/pwa";
119+
120+
/**
121+
* @returns {Promise<boolean>} A promise that resolves to true if the update was successfully activated and page reloaded, false otherwise.
122+
*/
123+
export async function JS_ActivatePWAUpdate() {
124+
const activated = await skipWaiting();
125+
126+
if (activated) {
127+
console.log("New service worker activated and controlling the page.");
128+
129+
return true;
130+
} else {
131+
console.warn("No waiting service worker found or activation failed via Mendix API.");
132+
return false;
133+
}
134+
}
135+
```
136+
137+
3. **Notifying users** — To not interrupt users during critical operations, Mendix recommends notifying them when an update becomes available. For example, you can implement a nanoflow that prompts users to confirm the update when a new version is detected. If the user confirms, the nanoflow can call `JS_ActivatePWAUpdate` to update. This nanoflow can be passed as a parameter to `JS_ListenForPWAUpdates`, which will invoke it when an update is detected.
138+
4. **Reload the Application** — Trigger a reload, or ask users to reload all open tabs or windows to ensure the application loads with the newly activated service worker.

0 commit comments

Comments
 (0)