1. El Ciclo de Vida del Service Worker en Nuxt 3
Construyendo aplicaciones web que funcionan sin conexión con experiencia nativa.
Una Progressive Web App (PWA) de nivel de producción no se limita a tener un archivo manifest.json para ser instalable. Su verdadero poder reside en un Service Worker programado para interceptar peticiones de red (Fetch Events), servir recursos desde Cache Storage y gestionar caídas de conectividad de forma invisible para el usuario.
En el ecosistema Nuxt 3, el módulo @vite-pwa/nuxt se integra con el pipeline de construcción de Vite y el servidor Nitro, pre-cacheando el App Shell y generando estrategias de runtime caching parametrizadas con Workbox.
App Shell vs Contenido Dinámico
El App Shell (HTML, CSS crítico, JS de la app) debe servirse mediante CacheFirst. Las APIs dinámicas deben usar StaleWhileRevalidate con límites estrictos de expiración.
2. Configuración de Estrategias de Caché con Workbox
Cómo cachear fuentes, imágenes y respuestas JSON de la API.
Diferentes recursos requieren diferentes políticas de persistencia. Los assets estáticos generados por Nuxt incluyen hashes inmutables en su nombre de archivo, lo que permite cachearlos agresivamente con CacheFirst por hasta un año.
Para fuentes de Google o CDNs externas, StaleWhileRevalidate permite servir la versión local al instante mientras se comprueba en segundo plano si existe una actualización.
export default defineNuxtConfig({
modules: ['@vite-pwa/nuxt'],
pwa: {
registerType: 'autoUpdate',
manifest: {
name: 'Juan Miguel Ruiz | Software Engineer',
short_name: 'Juan Miguel',
theme_color: '#ef4444',
background_color: '#0f172a',
display: 'standalone',
start_url: '/'
},
workbox: {
navigateFallback: '/',
globPatterns: ['**/*.{js,css,html,png,svg,ico,woff2}'],
runtimeCaching: [
{
urlPattern: /^https:\/\/fonts\.googleapis\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'google-fonts-cache',
expiration: { maxEntries: 10, maxAgeSeconds: 60 * 60 * 24 * 365 }
}
},
{
urlPattern: /^https:\/\/api\.github\.com\/.*/i,
handler: 'StaleWhileRevalidate',
options: {
cacheName: 'github-api-cache',
expiration: { maxEntries: 20, maxAgeSeconds: 60 * 60 * 2 }
}
}
]
}
}
})3. Detección Reactiva de Conexión en Vue 3
Informar al usuario de cambios de red y sincronizar datos en segundo plano.
Utilizando los eventos nativos online y offline del navegador junto con la reactividad de Vue 3 (o el composable useNetwork de @vueuse/core), podemos mostrar indicadores de estado sutiles y almacenar peticiones pendientes en IndexedDB para transmitirlas cuando la conexión se restablezca.
import { ref, onMounted, onUnmounted } from 'vue'
export function useNetworkStatus() {
const isOnline = ref(true)
const updateStatus = () => {
isOnline.value = navigator.onLine
}
onMounted(() => {
isOnline.value = navigator.onLine
window.addEventListener('online', updateStatus)
window.addEventListener('offline', updateStatus)
})
onUnmounted(() => {
window.removeEventListener('online', updateStatus)
window.removeEventListener('offline', updateStatus)
})
return { isOnline }
}4. Checklist de Validación PWA para Producción
Garantizar compatibilidad completa en iOS Safari, Android Chrome y Desktop.
1. Incluir iconos maskable y estándar de 192x192 y 512x512 en el manifest.
2. Configurar meta tags específicos para iOS: apple-mobile-web-app-capable y apple-touch-icon.
3. Validar que la navegación fuera de línea cargue la página de fallback sin errores de red.
4. Probar la actualización suave del Service Worker cuando se publica una nueva versión de la aplicación.