Cualquier sitio web puede convertirse en una PWA. Como una PWA se basa en HTML, CSS y JavaScript, basta con cumplir unos requisitos mínimos.
- HTTPS: el sitio debe usar HTTPS.
- Web manifest: aporta al navegador los metadatos de la PWA.
- Icono: permite mostrar la aplicación en la pantalla de inicio.
- Service Worker: procesa solicitudes y puede responder sin conexión.
- App Shell: el HTML que instala e inicia la PWA.
Web manifest
Un manifest sencillo incluye descripción, colores, iconos y direcciones:
{
"background_color": "#000000", "description": "Simple PWA",
"display": "standalone",
"icons": [
{"sizes": "180x180", "src": "./img/favicon-180.png", "type": "image/png"},
{"sizes": "192x192", "src": "./img/favicon-192.png", "type": "image/png"},
{"sizes": "512x512", "src": "./img/favicon-512.png", "type": "image/png"}
],
"id": "/", "name": "Simple PWA", "scope": "./",
"short_name": "Simple PWA", "start_url": "./", "theme_color": "#000000"
}
Iconos
Los iconos representan la aplicación en la pantalla de inicio, la barra
de tareas y el selector de aplicaciones. Ofrece varios tamaños,
incluidos 192x192 y 512x512 para Android y 180x180 para Apple, en
PNG o SVG.
Service Worker
Para instalar la aplicación en el teléfono, el service worker debe proporcionar al menos acceso sin conexión al app shell. No es obligatorio guardar los demás recursos:
'use strict';
const CACHE_STATIC = 'static-cache-v1';
const FILES_TO_CACHE = ['./', './favicon.ico', './img/favicon-512.png', './index.html', './pwa.json'];
function onFetch(evt) {
async function cacheOrFetch(req) {
const cache = await self.caches.open(CACHE_STATIC);
const cached = await cache.match(req);
return cached ?? await fetch(req);
}
evt.respondWith(cacheOrFetch(evt.request));
}
function onInstall(evt) {
evt.waitUntil(Promise.all(FILES_TO_CACHE.map((url) => caches.open(CACHE_STATIC).then((cache) => cache.add(url)))));
}
self.addEventListener('fetch', onFetch);
self.addEventListener('install', onInstall);
App Shell
El app shell suele ser el archivo principal, index.html. Indica al
navegador dónde está el manifest y registra el service worker:
<link rel="manifest" href="./pwa.json">
<script>
if ('serviceWorker' in navigator) {
self.addEventListener('load', async () => {
const container = navigator.serviceWorker;
if (container.controller === null) await container.register('sw.js');
});
}
</script>
Conclusión
Casi cualquier sitio puede convertirse en una PWA siguiendo estas reglas. Sin embargo, una PWA mínima solo coloca el icono en la pantalla de inicio. Para aprovechar las Web API modernas, la aplicación debe diseñarse desde el principio pensando en funcionamiento offline, almacenamiento local y cálculo en el cliente.