---
title: "Progressive Web App (PWA) support"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Progressive Web App (PWA) support}
%\VignetteEngine{knitr::rmarkdown}
%\VignetteEncoding{UTF-8}
---
```{r, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>"
)
```
```{r setup, message=FALSE, echo=FALSE}
library(shinyMobile)
```
The following book provides more in depth [review](https://unleash-shiny.rinterface.com/mobile-pwa) about PWA support.
PWAs are web applications that are regular web pages or websites, but can appear to the user like traditional applications or native mobile applications. They can be __installed__ on the device, provide __offline__ features, can be __launched from the home screen__, and have a __fullscreen__ display.
In essence, PWAs are websites. They have the same basic features as any other website: at least one HTML page, which very probably loads some CSS and JavaScript. But a PWA has some additional requirements as well:
- A **manifest**: a JSON file specifying app metadata like its name, icons to use for user’s home screen and launch screen, and theme colors.
- A **service worker** that can cache the app content, thereby making sure to provide basic offline support.
Luckily, this is can all be handled by `{shinyMobile}` and `{charpente}`.
## Configuration
`{shinyMobile}` is PWA capable, meaning that you can make sure your app uses the correct assets to be used as a PWA. This feature is automatically handled by `f7Page()` if `allowPWA` is `TRUE`.
When set to `TRUE`, your app is set up to use both a `service-worker.js` script and a `manifest.webmanifest` file that you will provide.
To create these necessary assets for your PWA, you can use `{charpente}`:
```r
remotes::install_github("RinteRface/charpente")
library(charpente)
set_pwa(APP_PATH, ...)
```
Where `APP_PATH` is the app location. Currently, it only works if the app is **inside a package** like with [`{golem}`](https://github.com/ThinkR-open/golem). If your app is not in a package, you may copy the `www` folder of the [gallery app](https://github.com/RinteRface/shinyMobile/tree/master/inst/examples/gallery/www), which provides:
- A valid `service-worker.js`.
- A valid web manifest (`manifest-webmanifest`). Don't forget to change the `start_url` property to the path of your app.
- As a bonus a valid `offline.html` fallback, which is displayed when the app is offline.
- A valid set of icons. There are tools such as [appsco](https://appsco.pe/developer/splash-screens) and [app-manifest](https://app-manifest.firebaseapp.com), to create
those custom icons and splash screens, if you need to.
It is really easier with `{charpente}`, the reason why we strongly recommend to develop your app inside a package.
But that's not all that's needed! When you set `allowPWA = TRUE` in `f7Page()`, the app will also attach the [Google PWA compatibility script](https://github.com/GoogleChromeLabs/pwacompat), called PWACompat, which will help with PWA compatibility. More specifically, PWACompat brings the Web App Manifest to non-compliant browsers for better PWAs. This mostly means creating splash screens and icons for Mobile Safari, as well as supporting IE/Edge's Pinned Sites feature. It basically assures that the `manifest.webmanifest` file has a wider support.
## Using your PWA
The first step is to deploy your app somewhere. It doesn't matter where (shinyapps.io, Posit Connect, your own server, etc.), but you will need a URL to access it.
Then, you can follow these steps to install your app on your mobile device.
Copy the URL of your app in your mobile web browser (iOS: Safari and Andoid: Chrome). It opens like a classic web app, with top and bottom ugly navigation bars that are part of the browser UI.
- Select the share button located in the bottom bar of your iPhone/iPad For Android, you may do something similar. Importantly, Chrome for iOS does not support this feature, that's why we recommend using Safari.
- Click on "Add to Home Screen"
- Choose a relevant name and click on OK.
- The app will be added to your iOS/Android Apps. In case you want custom icons, replace the content of the www folder with your own.
## Limitations
It is actually quite complex to guarantee that all mobile platforms are supported.
The PWA compatibility script will work in most cases. If not, please open an issue [here](https://github.com/GoogleChromeLabs/pwacompat/issues), to help improving it!