PWA: come trasformare un sito web in app mobile installabile
Una Progressive Web App si installa sul telefono come un'app nativa, funziona offline e manda notifiche push. Come aggiungerla a un sito React o HTML esistente in meno di un'ora.
Pubblicato: 3 giugno 2025
Se hai già un sito web funzionante, puoi trasformarlo in un’app installabile sul telefono senza toccare gli app store, senza Swift, senza Kotlin. Su Android il browser propone automaticamente “Aggiungi alla schermata home” quando trova i requisiti minimi. Su iOS devi ancora farlo manualmente dal menu Safari, ma funziona. Il sito diventa un’icona, si apre senza barra dell’indirizzo, può funzionare offline.
I 3 ingredienti di una PWA
Una PWA è un sito web normale con tre aggiunte:
1. manifest.json — descrive l’app: nome, icona, colori, come si apre:
{
"name": "La Mia App",
"short_name": "App",
"start_url": "/",
"display": "standalone",
"background_color": "#ffffff",
"theme_color": "#0066cc",
"icons": [
{ "src": "/icon-192.png", "sizes": "192x192", "type": "image/png" },
{ "src": "/icon-512.png", "sizes": "512x512", "type": "image/png" }
]
}
Collegalo nell’<head> dell’HTML: <link rel="manifest" href="/manifest.json">.
2. Service Worker — uno script JavaScript che gira in background, intercetta le richieste di rete e gestisce la cache. Questo è il pezzo che abilita l’offline mode:
self.addEventListener('install', (e) => {
e.waitUntil(
caches.open('v1').then(c => c.addAll(['/', '/index.html', '/app.js', '/style.css']))
);
});
self.addEventListener('fetch', (e) => {
e.respondWith(
caches.match(e.request).then(cached => cached || fetch(e.request))
);
});
Questa strategia “cache-first” serve gli asset dalla cache locale quando disponibili. Per le chiamate API, usa invece “network-first”: prova la rete, usa la cache come fallback.
3. HTTPS — obbligatorio. Localhost è l’unica eccezione per lo sviluppo.
In React con Vite
Se usi Vite, il plugin vite-plugin-pwa automatizza tutto — genera il service worker, il manifest e i file di cache:
npm install -D vite-plugin-pwa
In vite.config.ts:
import { VitePWA } from 'vite-plugin-pwa'
export default {
plugins: [
VitePWA({
registerType: 'autoUpdate',
manifest: {
name: 'La Mia App',
short_name: 'App',
theme_color: '#0066cc',
icons: [
{ src: '/icon-192.png', sizes: '192x192', type: 'image/png' }
]
}
})
]
}
Questo genera automaticamente il service worker con Workbox, gestisce il precaching degli asset del build, e aggiorna silenziosamente l’app in background quando rilascia una nuova versione.
Offline mode e notifiche push
La pagina offline è quella che mostri quando l’utente non ha rete e cerca una pagina non in cache. Nel service worker, intercepta le richieste fallite e restituisci la pagina offline:
self.addEventListener('fetch', (e) => {
e.respondWith(
fetch(e.request).catch(() => caches.match('/offline.html'))
);
});
Le notifiche push sono tecnicamente possibili (Push API + server che chiama le subscription) ma richiedono un backend dedicato, gestione delle subscription per utente, e VAPID keys. Per la maggior parte dei progetti non servono: il valore principale di una PWA è l’installabilità e la velocità offline. Aggiungi le notifiche solo se hai un caso d’uso specifico — ordine consegnato, nuovo messaggio, alert di sistema.
Cosa fare
- Aggiungi
manifest.jsone il link nell’<head>oggi: è la modifica più veloce (15 minuti) e già questo abilita “Aggiungi a schermata home” su Android - Usa
vite-plugin-pwase sei su React/Vite: genera il service worker con Workbox in automatico e ti risparmia ore di debugging della cache - Testa con Chrome DevTools → tab Application → Manifest e Service Workers: Chrome ti dice esattamente cosa manca per soddisfare i criteri di installabilità