PWA /
Progressive Web App

01/2022 → 06/2023 par Gildas P. - Playing with pixels !
Version 1.0
Version 1.1 - L'app fonctionne aussi sans connexion internet

C'est quoi une Progressive Web App ?

Une PWA c'est un site web qu'on installe comme une vraie application (sur mobile par ex).

Avec pas mal d'avantages :

  • Un affichage plein écran, sans barre de navigation
  • Une icône d'application comme pour une application du store
  • La possibilité de consulter la web-app hors-ligne, sans connexion internet
  • Compatible iOS et Android, sans trop d'effort supplémentaire
  • C'est la classe, mon site est devenu une application mobile !
  • C'est parfait pour faire croire qu'on a fait un app quand on passe son diplôme

Sans le savoir vous avez déjà rencontré des Progressive Web Apps : Uber, Spotify, Pinterest, Flipboard, etc sont faites comme ça (source).

On peut donc tout à fait diffuser une PWA sur les appstores, et c'est une technologie qui n'est pas anecdotique.

Pour transformer un site web en "Progressive Web App" il faut :

  • une meta viewport dans le header html (recommandée dans tous les cas pour un site responsive)
  • une connexion https vers votre page (un serveur avec certificat SSL)
  • un "manifest" json qui décrit votre application
  • quelques icônes PNG
  • un worker Javascript...

→ Tout ça est déjà prêt dans un zip en fin d'article

Quelques icônes à différentes résolutions

Idéalement 512x512, 384x384, 256x256, 192x192, en PNG de préférence.

En réalité il suffit d'une icône 512x512, et votre mobile s'occupe de la redimentionner si besoin.

Le fichier "manifeste"

Le fichier "manifest.json" ressemble à ça, sous réserve que vous mettiez les icônes dans un dossier pwa-icons/ et le fichier manifest.json à la racine du site (sinon il faut changer les chemins indiqués) :

{
    "name": "Test Progressive Web App",
    "short_name": "PWA Test",
    "description": "Une webapp pour tester.",
    "display": "fullscreen",
    "orientation": "portrait",
    "scope": "./",
    "start_url": "./index.html",
    "theme_color": "#2196f3",
    "background_color": "#2196f3",
    "icons": [
        {
            "src": "./pwa-icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}
			
  • short_name c'est le nom qui apparait sous l'icône de l'application
  • description est tout à fait optionnelle
  • display peut prendre d'autres valeurs, mais si on installe un site web c'est bien pour l'avoir en plein écran...
  • orientation peut aussi avoir la valeur "landscape"
  • theme_color définit la couleur de l'éventuelle barre d'outils système (qui dépend de l'os)
  • background-color c'est la couleur de fond de la page de démarrage de l'application générée par l'os (avec l'icône et le titre indiqués)

Si vous avez d'autres icônes à d'autres formats il faut agrandit la section "icons" :

{
	...
    "icons": [
        {
            "src": "./pwa-icons/icon-192x192.png",
            "sizes": "192x192",
            "type": "image/png"
        },
        {
            "src": "./pwa-icons/icon-256x256.png",
            "sizes": "256x256",
            "type": "image/png"
        },
        {
            "src": "./pwa-icons/icon-384x384.png",
            "sizes": "384x384",
            "type": "image/png"
        },
        {
            "src": "./pwa-icons/icon-512x512.png",
            "sizes": "512x512",
            "type": "image/png"
        }
    ]
}
			


L'écran de démarrage de l'app,
qui dépend des paramètres indiqués dans manifest.json


Il faudra donc déclarer le manifeste dans le header html :

<link rel="manifest" href="manifest.json">

Le manifeste est placé à la racine du site...
Si vous le déplacez il faudra indiquer le bon chemin vers le fichier.

Le "worker" JS

C'est un script js qui va tourner en fond, pour piloter l'app de manière avancée; pour un site simple ça ne va pas servir.

Dans le cas présent le code va indiquer d'intercepter les fichiers de la page (images, scripts, etc) pour les mettre en cache, ce qui permettra d'ouvrir l'application même sans connexion internet.

De toute façon il faut un worker js pour pouvoir installer notre web-app, et j'ai préparé les 2 fichiers minimum requis, que vous n'aurez ni besoin de lire ni de modifier.

Il faut juste déclarer ceci dans le header html :

<script type="text/javascript" src="pwa-script.js"></script>

(Le 2ème fichier js est appelé par le fichier js ci-dessus)

 

→ Récap / Téléchargement

Concrètement, voici un zip avec tout ce qu'il vous faut

Incluant

  • le manifeste json (à personnaliser par vos soins)
  • le dossier d'icônes (à remplacer par les vôtres)
  • les fichiers javascript requis (pas besoin de les modifier)

Tout ça doit être copié à la racine du site.

Il faut donc ajouter à votre header html les 2 lignes suivantes :

<link rel="manifest" href="manifest.json">
<script type="text/javascript" src="pwa-script.js">
</script>

Job done !

Tester son manifeste sur pc/mac

Pour que ça fonctionne il faut obligatoirement un connexion https, il faut donc mettre vos fichiers sur un serveur qui dispose d'une certification SSL.

Firefox et Chrome proposent un outil d'inspection du manifeste dans les outils de développeur (F12).
Ca se passe dans l'onglet "Applications > Manifeste" et "Applications > Service Worker"...

Mais pour être honnête c'est beaucoup plus complet dans Chrome.

Une fois vérifié que vous n'avez pas de message d'erreur, ouvrez la page sur mobile (ça marche aussi sous certaines conditions sur desktop), et voilàààà !

Installer l'application sous Android

Sous Android utilisez Chrome (qui est forcément présent par défaut), ça marche moyen avec Firefox.

Avec un peu de chance une barre système s'affiche sur votre mobile, vous proposant d'installer l'application :

D'après mes tests ça dépend un peu du navigateur utilisé... et si vous dites "non", l'info-barre ne s'affichera plus avant un moment.

Dans tous les cas vous avez aussi la possibilité d'installer l'app manuellement depuis les options du navigateurs.


Petit bouton "Installer" en bas de la capture écran...

Installer l'application sous iOS

Sur iOS c'est plus compliqué, il n'y a aucune notification à l'écran, car Apple a décidé de privilégier la diffusion des PWA via l'app-store (oui, on peut mettre une pwa sur l'Apple Store !).

Du coup les gros sites corporate en PWA affichent un lien vers leur application sur l'Apple Store... qui sert en fait à installer leur site internet.

Ce qui est marrant c'est qu'on retrouvera aussi dans l'application le lien vers l'app-store... puisque l'app est en fait le site internet.

Quoi qu'il en soit, pour installer votre PWA manuellement sur iOS :

- il faut ouvrir le site dans Safari

- cliquer sur le bouton de partage (très peu instinctif)

- cliquer sur un truc du genre "Ajouter à l'écran d'accueil"

La webapp est alors installée comme sur Android, avec une vraie icône et tout.

Pas moyen de l'installer depuis Chrome ou Firefox ou autres sous iOS, il faut impérativement passer par Safari.

Le plus simple c'est donc de commencer avec un appareil Android pour vérifier que tout fonctionne bien !

Mettre à jour l'application

Maintenant que tout marche, comment faire pour mettre à jour l'app ?

Et bien très simplement : c'est un site internet, si vous changez des fichiers sur le serveur ça se répercutera directement chez l'utilisateur, à la prochaine ouverture de l'application.

Si l'utilisateur est hors connexion il continuera de voir l'ancienne version, mais ça se mettra à jour dès qu'il sera connecté.

Simple et efficace.

En cas de problème de fichiers hors connexion

Normalement tous les fichiers du site sont automatiquement mis en cache, pour une utilisation ultérieure hors connexion.
Mais j'ai rencontré parfois des soucis avec des fichiers css qui ne semblaient pas vouloir se mettre en cache automatiquement.

Dans ce cas vous avez la possibilité d'indiquer manuellement quelques fichiers à mettre en cache dès l'installation.

Ca se passe dans pwa-worker.js, en début de page, il y a une ligne :

var cacheFilesList = [];

dans laquelle vous pouvez lister les fichiers à mettre en cache manuellement, du genre :

var cacheFilesList = ["css/style.css", "css/truc.css", "pwa.zip"];

Attention, si 1 seul des fichiers n'existe pas, ça ne marchera plus du tout !

Ajouter un bouton html-css pour proposer d'installer votre site

Parce que si on doit aller dans le menu du navigateur c'est pas très user-friendly... mais c'est plus compliqué qu'il y parait.

Le truc c'est qu'il va falloir afficher le bouton en question seulement si l'app n'est pas déjà installée; il doit diparaître une fois l'application installée avec succès.
Et tout ça se passe en Javascript... je n'ai pas encore essayé, mais la solution se trouve ici.

D'autres possibilités à creuser...

  • Déclarer les fichiers à enregistrer pour une utilisation hors-ligne Ca c'est fait, le code que je vous propose gère la mise en cache des fichiers du site, votre application devrait donc être 100% utilisable même sans connexion internet.
  • Utilisation du Local Storage pour stocker des données utilisateur (score, stats, etc)
  • Utiliser les fonctionnalités de partage (réseaux sociaux, etc) natives sur mobile

Voici quelques liens pour creuser :