# PWA

Elk provides a PWA (Progressive Web App) that can be installed on your desktop/device. This allows you to use Elk as a native app on your device, and it will work offline.

The main goal of the PWA is to provide a native app experience on mobile devices with Web Push Notifications and Web Share Target API capabilities.

Web Share Target will allow you to share content from other apps to Elk in mobile browsers.

## Mobile Support

Some mobile browsers will allow you to install the PWA as a native app, and some others will only allow you to add the PWA to your home screen.

If you're using a mobile browser that supports the PWA installation, you will see a banner at the bottom of the screen with the option to install the PWA.

If the browser also supports [beforeinstallprompt](https://web.dev/customize-install/) event, ElK will show a prompt (on the right aside on wide screens, or at top on small screens) to allow you to install the PWA directly.

If the browser doesn't support the PWA installation, check following entries:

### Safari iOS

Right now, you cannot use Web Push Notifications on Safari mobile browsers, since it doesn't support the Web Push API yet at operating system level.

You can check the status of the Push API on Safari mobile browsers on [this page](https://caniuse.com/notifications).

Visit also [this site](https://firt.dev/notes/pwa-ios/) to check the status of PWA Capabilities on Safari mobile browsers.

To install a Progressive Web App (PWA) on Safari, follow these steps:
- Tap the "Share" icon at the bottom of the screen.
- Scroll down and tap "Add to Home Screen".
- Customize the name of the app (if desired) and tap "Add".
- The PWA should now appear on your home screen.

### Other browsers on iOS

Browsers on iOS other than Safari (like Chrome) are very limited on PWA functionalities. Besides Web Push Notifications (like in Safari) not even PWA installation is supported.

If you are using one of these browsers and want to add Elk to your homescreen, you will have to use Safari and follow the instructions above.

### Firefox

To install a Progressive Web App (PWA) on Firefox, follow these steps:
- Look for the install button or icon, usually located in the address bar or in a prompt that appears on the screen.
- Click on the install button or icon and follow the prompts to complete the installation.
- If you don't see an install button or icon, you can look for the PWA in the Firefox menu. Click on the three horizontal lines in the top/bottom right corner of the browser window to open the menu, then click on "Install" option.

### Chromium based browsers

To install a Progressive Web App (PWA) on Chromium based browsers, such as Google Chrome, Microsoft Edge, or Brave, follow these steps:
- Click on the menu button (three vertical dots) at the top right corner of the screen.
- Select "Install Elk as app" or "Install Elk to Home screen".
- Customize the name of the app (if desired) and click "Install" or "Add".
- The PWA should now appear on your device's home screen or in your app drawer.

## FAQ

This FAQ is related to the PWA application on Elk, if you can't find the answer to your problem here, you can [file an issue on Elk's repository in GitHub](https://github.com/elk-zone/elk).

### Could not subscribe to push notifications

In Elk application, you can only have one push subscription per backend server, so if you have already subscribed to push notifications in another account with different backend, you will not be able to subscribe to push notifications. If that's the case, you will need to switch to the account which is subscribed to push notifications and unsubscribe it.

This is a limitation of any browser, and it's not related only to Elk application.

If you deleted any account from your backend with push notification subscription enabled in Elk, you will need to remove the push notification subscriptions from your browser:
- [Chrome - Web and Android](https://www.connecto.io/kb/knwbase/how-to-unsubscribe-from-chrome-notifications-on-web-and-android/).
- Firefox:
  - Open settings
  - Click on "Privacy & Security" menu entry
  - Scroll down in the page and locate "Permissions > Notifications"
  - Click on "Configuration" button
  - Locate "Elk" website in the list and select it, then click on "Remove website" button
- Safari (WIP) 

### Permission denied: enable notifications in your browser

Before enabled push notifications in your browser, you need to enable notifications, Elk will instruct the browser to show a notification permission prompt.

If you cannot see the notification permission prompt, you will need to remove push notification subscriptions, check previous entry.

### Your browser supports Web Push Notifications, but does not seem to implement the VAPID protocol.

If you're receiving this error, it means that either your browser doesn't support the VAPID protocol, or something is preventing the VAPID protocol from working in your browser. The VAPID protocol requires the clock to be set correctly on your computer or device, since this is used for certficate checks. Check that your clock is set to the correct date, time and timezone. After setting it correctly, restart your browser and try again. If it is set correctly, and you still receive this message, then your browser doesn't support the VAPID protocol and you will not be able to receive push notifications.

In Brave Browser, you will need to allow "Use Google Services for Push Messaging" in "Settings" > "Privacy and security".

There is nothing we can do to fix this, you will need to use a browser that supports the VAPID protocol: Chrome, Brave, Edge, Safari, Firefox and Vivaldi.

### Install Elk button not working

There are browsers that allows applications to provide a custom PWA installation prompt, but there are also browsers with that behavior broken, for example Arc browser.

There is nothing we can do to fix this problem, you will need to check browser documentation to install the PWA.

## PWA Configuration in Elk project

By default, Elk will enable the PWA integration, but can be disabled by setting `VITE_DEV_PWA` to `false` in your `.env` file.

You can find the configuration options for the PWA in the [config/pwa.ts](https://github.com/elk-zone/elk/blob/main/config/pwa.ts) module.

### PWA Web Manifest

Right now, there is no support for web manifest internationalization and theme color in any browser, we're using a custom module to generate web manifests for theme color and language variants.

Elk will generate 2 web manifests per locale, one for light theme and one for dark theme.

You can check web manifest generation on [modules/pwa/i18n.ts](https://github.com/elk-zone/elk/blob/main/modules/pwa/i18n.ts) module.

### PWA Icons

Elk's favicon and PWA icons are generated from [Elk's SVG Logo](https://github.com/elk-zone/elk/blob/main/public/logo.svg) via [custom script](https://github.com/elk-zone/elk/blob/main/scripts/generate-pwa-icons.ts), using [sharp](https://github.com/lovell/sharp/) and [sharp-ico](https://github.com/ssnangua/sharp-ico) libraries:
- favicon.ico: transparent 64x64 32-bits icon
- pwa-64x64.png: transparent 64x64 8-bits icon (optimized from 32-bits color)
- pwa-192x192.png: transparent 192x192 8-bits icon (optimized from 32-bits color)
- pwa-512x512.png: transparent 512x512 8-bits icon (optimized from 32-bit color)
- maskable-icon.png: white background 512x512 8-bits icon (optimized from 32-bits color)
- apple-touch-icon.png: white background 180x180 8-bits icon (optimized from 32-bits color)

### PWA UI Components

Elk will provide a set of UI components to allow you to customize the PWA installation prompt on browsers with [beforeinstallprompt](https://web.dev/customize-install/) support.

You can find the PWA installation prompt in the [PwaInstallPrompt](https://github.com/elk-zone/elk/blob/main/components/pwa/PwaInstallPrompt.client.vue) component: will be shown on the right aside on wide screens, or at top on small screens.

Elk is using prompt for update strategy, so the PWA prompt for update will be shown only if there is a new version of Elk available.

On small screens, the PWA prompt for update will be shown as a button on the head, you can find it in [PwaBadge](https://github.com/elk-zone/elk/blob/main/components/pwa/PwaBadge.client.vue) component.

On wide screens, the PWA prompt for update will be shown as a prompt on the right aside, you can find it in [PwaPrompt](https://github.com/elk-zone/elk/blob/main/components/pwa/PwaPrompt.client.vue) component.

PWA prompt for update will take preference over PWA installation prompt, so if there is a new version of Elk available, the PWA prompt for update will be shown instead of the PWA installation prompt.

All previous UI components don't have any logic, all them will use the logic provided by the [PWA plugin](https://github.com/elk-zone/elk/blob/main/modules/pwa/runtime/pwa-plugin.client.ts).

### Service Worker

You can find Elk custom service worker in [service-worker folder](https://github.com/elk-zone/elk/blob/main/service-worker), it provides:
- [Prompt for update strategy](https://github.com/elk-zone/elk/blob/main/service-worker/sw.ts#L14).
- [Web Push Notifications](https://github.com/elk-zone/elk/blob/main/service-worker/web-push-notifications.ts): [push notifications](https://github.com/elk-zone/elk/blob/main/service-worker/sw.ts#L105) and [push notification click](https://github.com/elk-zone/elk/blob/main/service-worker/sw.ts#L106).
- [Web Share Target API](https://github.com/elk-zone/elk/blob/main/service-worker/share-target.ts): [share target registration](https://github.com/elk-zone/elk/blob/main/service-worker/sw.ts#L107).

### Push Notifications Subscription Logic

Elk will allow you to send push notifications to your users, you can find the logic for Web Push Notifications subscription [composables/push-notifications folder](https://github.com/elk-zone/elk/blob/main/composables/push-notifications).

There is a limitation on browsers about registering multiple Web Push Notifications: you can only subscribe to one push service per browser per application: trying to register multiple push subscriptions will be treated as spam by the browser.

If you try to register multiple push subscriptions, the browser will throw an error, and you will need to unregister the previous push subscription before registering a new one.

### Debugging PWA in development

To debug the PWA in development, you will need to run `dev:pwa` or `dev:mocked:pwa` script.

Running one of previous scripts will start a development server with the PWA enabled: you can review the web manifests and debug the service worker in your browser, use any Chromium based browser, since we're registering the service worker using `type: 'module'`.

You can debug Web Push Notifications in desktop and mobile browser and Web Share Target in your mobile device, using the same URL as the development server.

Right now, we can only debug on Android Chrome mobile browsers:
- Web Push Notifications: you don't need to install de PWA, just enable the notifications in the browser on notifications page or web push notifications settings page.
- Web Share Target: you need to install the PWA, and then you can share content from other apps to Elk.

### Debugging PWA in mobile browsers

To debug the PWA service worker in your mobile browser, you will need to:
1) Enable development options in your Android device:
  - Go to "Settings" on your device.
  - Scroll down to "About phone" and tap it.
  - Locate the "Build number" and tap it repeatedly (usually 7 times) until you see a message saying that you have enabled developer options.
  - Go back to "Settings" and you should now see "Developer options" listed.
  - Tap on "Developer options" and you can enable various settings such as USB debugging, mock locations, and more.
2) Connect your Android device to your computer using a USB cable.
3) Enable USB debugging in your Android device:
  - Go to "Settings" on your device.
  - Scroll down to "Developer options" and tap it.
  - Enable "USB debugging".
  - Confirm the prompt on your device to allow USB debugging.
  - Open Chrome/Edge browser in your device.
4) Open Chrome on your computer and go to `chrome://inspect/#devices`.
  - Your device should be listed in the "Remote Target" section after a few seconds (if not, open Chrome/Edge and navigate to any page).
  - Click the "Port forwarding..." button and type "5314" into the "Port" input and "localhost:5314" into the "IP address and port" input, then press "Done".
  - Enter `http://localhost:5314` in the "Open tab with url" input and click the "Open" button.
  - Click on the "Inspect" button to open the DevTools.
5) Remember to remove the service worker from your device browser using dev tools once you finish testing the service worker:
  - Go to `Application > Storage`, you should check following checkboxes:
    - Application: `[x]` Unregister service worker
    - Storage: `[x]` Local and session storage `[x]` IndexedDB
    - Cache: `[x]` Cache storage and `[x]` Application cache
  - Click on Clear site data button
  - Go to `Application > Service Workers` and check the current service worker is missing or has the status deleted or reduntant.
6) Disable port forwarding: open the "Port forwarding..." modal again on the `chrome://inspect/#devices` page and either uncheck the "Enable port forwarding" option or remove the entry from the list and click "Done". 

## PWA web manifest and related applications

When adding your application to the `related_applications` PWA web manifest property, you will need some info about them.

### Microsoft Store

Elk is available on Microsoft Store, you can find it in the following url: [Elk](https://www.microsoft.com/store/apps/9N8GZJZQZJZB).

If you want to add your app published in the Microsoft Store as a related application, check the following link: https://learn.microsoft.com/en-us/mem/configmgr/protect/deploy-use/find-a-pfn-for-per-app-vpn#find-a-pfn-if-the-app-is-not-installed-on-a-computer.

To add your application to the related application entry:
- locate `Store ID`: for Elk it is `9N8GZJZQZJZB`
- visit the following url (replace `9PNZMMXQHQZ5` with your `Store ID`): https://bspmts.mp.microsoft.com/v1/public/catalog/Retail/Products/9PNZMMXQHQZ5/applockerdata

From the previous url, you will get a json file as response:
```json
{
  "packageFamilyName": "53213ElkTeam.Elk_6x2f3wfg7gnst",
  "packageIdentityName": "53213ElkTeam.Elk",
  "windowsPhoneLegacyId": "cf793b8f-863a-45cd-936c-11519a995096",
  "publisherCertificateName": "CN=B976409D-CB14-4908-A1DF-47FAA5352A5B"
}
```

Use the `packageFamilyName` value as the `id` in your `related_applications` entry, for Elk results in (replace `9PNZMMXQHQZ5` with your `Store ID` in the url entry):
```json
{
  "related_applications": [{
    "platform": "windows",
    "url": "https://www.microsoft.com/store/apps/9PNZMMXQHQZ5",
    "id": "53213ElkTeam.Elk_6x2f3wfg7gnst"
  }]
}
```

<!--

## PlayStore

WIP

## Apple Store

WIP

-->
