Introduction
La plupart des sites se chargent. Une PWA survit.
Lorsqu’un utilisateur perd sa connexion Internet, une application React classique affiche un écran vide ou une erreur. Une Progressive Web App continue de fonctionner — en servant des pages mises en cache, en préservant l’expérience et en se resynchronisant lorsque la connexion revient.
Ajouter le support PWA à une application React avec Vite est l’un des gains les plus importants que vous pouvez obtenir en performance, fidélisation et scores Lighthouse. Ce guide montre exactement comment je l’ai mis en œuvre dans Dywan Dev et Savoura Dywan — avec l’invite d’installation, la page hors ligne et la notification de mise à jour que la plupart des tutoriels omettent.
Qu’est-ce qu’une PWA et pourquoi c’est important
Une Progressive Web App est une application web qui se comporte comme une application native. Elle peut être installée sur l’appareil de l’utilisateur, fonctionner hors ligne, se charger instantanément aux visites suivantes et envoyer des notifications push.
Pour les entreprises, cela se traduit par moins de rebonds et plus d’engagement. Pour les développeurs, par de meilleurs scores Lighthouse et une offre produit plus solide. Pour vous, en tant que freelance ou vendeur de templates — c’est une fonctionnalité pour laquelle les clients paient davantage.
Les trois exigences centrales d’une PWA sont un manifeste web, un service worker et HTTPS. Vite rend les trois accessibles simplement avec un seul plugin.
1. Installer le plugin Vite PWA
npm install -D vite-plugin-pwa
Ce plugin génère automatiquement le service worker et injecte le manifeste. Il s’appuie sur Workbox — la même bibliothèque que Google utilise pour l’outillage PWA.
2. Configurer le plugin dans vite.config.js
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import { VitePWA } from 'vite-plugin-pwa';
export default defineConfig({
plugins: [
react(),
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.ico', 'apple-touch-icon.png', 'mask-icon.svg'],
manifest: {
name: 'Dywan Dev',
short_name: 'DywanDev',
description: 'Modern web templates and fullstack solutions',
theme_color: '#0f172a',
background_color: '#0f172a',
display: 'standalone',
scope: '/',
start_url: '/',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable'
}
]
},
workbox: {
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}'],
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-cache',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 24 * 365
}
}
}
]
}
})
]
});
Remplacez le nom, la description et la couleur de thème par votre propre identité visuelle. Les icônes doivent exister dans votre dossier public/ — générez-les à partir de votre logo avec un outil comme PWA Asset Generator.
3. Créer une page de repli hors ligne
C’est ce qui distingue une vraie PWA d’une simple configuration de service worker. Sans Internet, proposez quelque chose d’utile plutôt qu’une erreur du navigateur.
Créez public/offline.html :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>You're Offline</title>
<style>
body {
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
height: 100vh;
margin: 0;
background: #0f172a;
color: #f8fafc;
text-align: center;
padding: 2rem;
}
h1 { font-size: 2rem; margin-bottom: 1rem; }
p { color: #94a3b8; max-width: 400px; }
</style>
</head>
<body>
<h1>You're offline</h1>
<p>It looks like you lost your connection. The page you're looking for will be available once you're back online.</p>
</body>
</html>
Référencez-la dans la configuration Workbox de vite.config.js (ajoutez navigateFallback à côté de vos globPatterns existants) :
workbox: {
navigateFallback: '/offline.html',
globPatterns: ['**/*.{js,css,html,ico,png,svg,woff2}']
}
4. Ajouter une invite d’installation
Les navigateurs affichent une invite d’installation native — mais vous pouvez l’intercepter et afficher votre propre interface au bon moment. Cela augmente fortement le taux d’installation.
Créez src/hooks/usePWAInstall.js :
import { useState, useEffect } from 'react';
export const usePWAInstall = () => {
const [installPrompt, setInstallPrompt] = useState(null);
const [isInstallable, setIsInstallable] = useState(false);
useEffect(() => {
const handler = (e) => {
e.preventDefault();
setInstallPrompt(e);
setIsInstallable(true);
};
window.addEventListener('beforeinstallprompt', handler);
return () => window.removeEventListener('beforeinstallprompt', handler);
}, []);
const install = async () => {
if (!installPrompt) return;
await installPrompt.prompt();
const { outcome } = await installPrompt.userChoice;
if (outcome === 'accepted') setIsInstallable(false);
setInstallPrompt(null);
};
return { isInstallable, install };
};
Utilisez-le dans n’importe quel composant :
import { usePWAInstall } from './hooks/usePWAInstall';
export const InstallButton = () => {
const { isInstallable, install } = usePWAInstall();
if (!isInstallable) return null;
return (
<button onClick={install} className="install-btn">
Install App
</button>
);
};
Placez ce bouton dans la barre de navigation ou la section héro. Il n’apparaît que lorsque le navigateur considère l’app installable — il ne s’affiche donc jamais inutilement.
5. Ajouter une notification de mise à jour
Lorsque vous déployez une nouvelle version, les utilisateurs qui ont encore l’ancien service worker en cache ne verront pas vos changements automatiquement. Affichez-leur une notification pour qu’ils puissent actualiser et obtenir la dernière version.
Mettez à jour src/main.jsx :
import { registerSW } from 'virtual:pwa-register';
const updateSW = registerSW({
onNeedRefresh() {
const confirmed = window.confirm(
'A new version is available. Reload to update?'
);
if (confirmed) updateSW(true);
},
onOfflineReady() {
console.log('App is ready to work offline');
}
});
Pour une expérience plus soignée, remplacez window.confirm par une notification toast personnalisée avec vos composants UI existants.
6. Vérifier que tout fonctionne
Lancez la build et prévisualisez en local :
npm run build
npm run preview
Ouvrez ensuite Chrome DevTools → Application → Service Workers. Vous devriez voir votre service worker enregistré et actif. Vérifiez l’onglet Manifest pour valider icônes et métadonnées.
Lancez un audit Lighthouse. Une PWA correctement configurée devrait obtenir des scores verts en Performance, Accessibilité et PWA.
Conclusion
Le support PWA est une de ces fonctionnalités qui ne coûte que quelques heures à implémenter et rapporte en continu — en scores Lighthouse, rétention et perception côté client. Lorsque vous expliquez à un client que son site fonctionne hors ligne et peut s’installer sur un téléphone comme une app native, la discussion avance.
Chaque template que je construis chez Dywan Dev inclut le support PWA par défaut. Ce n’est pas une option — c’est le standard.
Restaurant, portfolio ou site vitrine ? Les templates Dywan Dev sont prêts pour la PWA, multilingues et optimisés dès le départ. Découvrir les templates.
