Como añadir un service worker básico con Workbox en WordPress en WordPress

Contents

Introducción

Este artículo explica paso a paso cómo añadir un service worker básico utilizando Workbox en un sitio WordPress. Cubre desde una implementación rápida con el CDN de Workbox hasta una integración más robusta con build usando workbox-build, además de cómo servir el archivo desde la raíz del sitio (requisito para mayoría de los casos) y buenas prácticas de cacheo, actualización y depuración.

Requisitos previos

  • WordPress actualizado.
  • Acceso al servidor para colocar archivos en la raíz (o permiso para que un plugin escriba en la raíz).
  • Conexión segura HTTPS en producción (los service workers requieren HTTPS excepto en localhost).
  • Conocimientos básicos de PHP y JavaScript.

Conceptos claves

  • Scope: el alcance del service worker depende de la ubicación del archivo. Para controlar toda la web, el archivo debe estar en la raíz: /service-worker.js.
  • Precaching: Workbox permite precargar recursos críticos al instalar el worker.
  • Runtime caching: estrategias (NetworkFirst, CacheFirst, StaleWhileRevalidate) para peticiones que no están en el precache.
  • Actualización: gestión de versiones y activación con skipWaiting() y clients.claim().

Opción rápida: usar Workbox desde el CDN (ideal para empezar)

Esta opción sirve para aprender y probar. Crea un archivo service-worker.js que importe Workbox desde su CDN y defina precache y reglas de cache runtime.

Ejemplo de service-worker.js (colocado idealmente en la raíz como /service-worker.js)

importScripts(https://storage.googleapis.com/workbox-cdn/releases/6.5.4/workbox-sw.js)

if (workbox) {
  // Forzar versión del cache (útil durante desarrollo)
  workbox.core.setCacheNameDetails({prefix: mi-sitio, suffix: v1})

  // Hacer que el nuevo SW tome control inmediatamente
  self.addEventListener(message, (event) =gt {
    if (event.data  event.data.type === SKIP_WAITING) {
      self.skipWaiting()
    }
  })

  // Precaching básico (puedes incluir archivos estáticos)
  workbox.precaching.precacheAndRoute([
    {url: /offline.html, revision: 1},
    {url: /wp-content/themes/tu-tema/css/estilos.css, revision: 1},
    // Añade aquí otros recursos que quieras precachear
  ])

  // App shell / navegación: si falla la red, responder con offline.html
  workbox.routing.registerRoute(
    // Comprobador de navegación
    ({request}) =gt request.mode === navigate,
    new workbox.strategies.NetworkFirst({
      cacheName: pages-cache,
      plugins: [
        new workbox.expiration.ExpirationPlugin({maxEntries: 50})
      ]
    })
  )

  // Imágenes: CacheFirst con límite
  workbox.routing.registerRoute(
    ({request}) =gt request.destination === image,
    new workbox.strategies.CacheFirst({
      cacheName: images-cache,
      plugins: [
        new workbox.expiration.ExpirationPlugin({maxEntries: 60, maxAgeSeconds: 30  24  60  60})
      ]
    })
  )

  // Recursos CSS/JS: StaleWhileRevalidate
  workbox.routing.registerRoute(
    ({request}) =gt request.destination === script  request.destination === style,
    new workbox.strategies.StaleWhileRevalidate({
      cacheName: assets-cache,
      plugins: [
        new workbox.expiration.ExpirationPlugin({maxEntries: 60})
      ]
    })
  )

} else {
  console.error(Workbox no se ha cargado)
}

Registrar el service worker desde WordPress (front-end)

Registra el service worker con un pequeño script que se encola en el front-end. Ejemplo de función para functions.php o un plugin:

add_action(wp_enqueue_scripts, function() {
  // Solo en front-end
  if ( ! is_admin() ) {
    wp_enqueue_script(sw-register, get_stylesheet_directory_uri() . /js/sw-register.js, array(), null, true)
  }
})

Contenido de js/sw-register.js:

if (serviceWorker in navigator) {
  window.addEventListener(load, function() {
    navigator.serviceWorker.register(/service-worker.js, {scope: /})
      .then(function(reg) {
        console.log(Service worker registrado con scope:, reg.scope)
      })
      .catch(function(err) {
        console.error(Registro de service worker falló:, err)
      })
  })
}

Servir el service-worker.js desde la raíz (requisito común)

Como el scope por defecto limita el alcance al directorio del archivo, la forma más sencilla de que el worker controle toda la web es servirlo desde la raíz en /service-worker.js. Dos formas habituales:

  • Colocar manualmente el archivo en la carpeta raíz del sitio (necesita acceso FTP/SSH).
  • Crear un plugin que copie o genere service-worker.js en la raíz durante la activación.

Ejemplo sencillo de plugin que escribe service-worker.js en la raíz al activarse

/
Plugin Name: SW Root Writer
Description: Escribe service-worker.js en la raíz al activar el plugin.
Version: 1.0
/

register_activation_hook(__FILE__, sw_writer_activate)
register_deactivation_hook(__FILE__, sw_writer_deactivate)

function sw_writer_activate() {
  sw_path = ABSPATH . service-worker.js
  content = file_get_contents(plugin_dir_path(__FILE__) . templates/service-worker-template.js)
  // Escribe el archivo en la raíz
  file_put_contents(sw_path, content)
}

function sw_writer_deactivate() {
  sw_path = ABSPATH . service-worker.js
  if (file_exists(sw_path)) {
    unlink(sw_path)
  }
}

En el archivo templates/service-worker-template.js pondrías el código JS del service worker (igual al ejemplo Workbox anterior). Ten en cuenta que esto requiere permisos de escritura en ABSPATH y puede ser bloqueado en entornos gestionados.

Integración avanzada: build con workbox-build (injectManifest)

Para proyectos más serios conviene usar workbox-build (o el plugin de Workbox para webpack) y generar un precache manifest que se inyecta en el service worker para controlar versiones y cacheado con precisión.

Ejemplo de script de Node con injectManifest

const { injectManifest } = require(workbox-build)

injectManifest({
  swSrc: src/sw-template.js, // plantilla con self.__WB_MANIFEST
  swDest: build/service-worker.js,
  globDirectory: build/,
  globPatterns: [
    /.{html,js,css,png,jpg,svg}
  ],
}).then(({count, size}) => {
  console.log(Se precachearon {count} archivos, tamaño total {size} bytes.)
})

Ejemplo de plantilla src/sw-template.js:

importScripts(https://storage.googleapis.com/workbox-cdn/releases/6.5.4/workbox-sw.js)

workbox.precaching.precacheAndRoute(self.__WB_MANIFEST  [])

workbox.routing.registerRoute(
  new RegExp(/wp-json/),
  new workbox.strategies.NetworkFirst()
)

Después del build, copia build/service-worker.js a la raíz del sitio o usa el plugin que copia archivos durante el despliegue.

Estrategias de cache recomendadas

  • HTML de páginas: NetworkFirst para mantener contenido actualizado y fallback al cache cuando no haya red.
  • APIs / JSON: NetworkFirst con políticas de expiración si son datos críticos StaleWhileRevalidate si la frescura no es esencial.
  • Imágenes: CacheFirst con un límite de entradas y expiración.
  • Assets estáticos (CSS/JS): StaleWhileRevalidate para buena velocidad y actualización en background.

Manejo de actualizaciones y control de versiones

  • Usa una versión en el nombre del cache o en workbox.core.setCacheNameDetails para invalidar caches cuando publiques cambios.
  • Implementa skipWaiting() y clients.claim() para que el nuevo service worker tome el control inmediatamente, y considera mostrar un aviso al usuario para recargar cuando haya nueva versión.
  • Para activar skipWaiting desde la página, envía un mensaje al SW registrado:
// Desde el cliente web (por ejemplo, sw-register.js)
if (navigator.serviceWorker.controller) {
  navigator.serviceWorker.controller.postMessage({type: SKIP_WAITING})
}

Fallback offline y página offline

Incluye una página offline (por ejemplo /offline.html) en el precache y responde con ella para navegaciones cuando la red no esté disponible. Así mejoras la experiencia del usuario.

Depuración y pruebas

  1. Usa Chrome DevTools > Application > Service Workers para ver el estado, forzar actualización, eliminar el worker, y ver los caches.
  2. Activa la opción Bypass for network para comprobar comportamiento sin cache o desactívala para probar caches.
  3. Comprueba la consola para mensajes del registro del worker y errores de importScripts (fallo en cargar Workbox si CDN bloqueado).
  4. Prueba en entornos locales con HTTPS o en localhost (localhost permite service workers sin HTTPS).

Buenas prácticas y seguridad

  • Asegura que tu sitio funcione correctamente sin el service worker si algo falla (graceful degradation).
  • No cachees nunca información sensible sin las debidas consideraciones (autenticación, datos personales).
  • Comprueba cabeceras CORS si traes recursos desde dominios externos y quieres cachearlos.
  • Documenta la estrategia de caches y versiones para que todo el equipo la entienda.

Resumen: pasos mínimos para un service worker básico con Workbox en WordPress

  1. Crear el archivo service-worker.js (idealmente en la raíz) con importScripts de Workbox y reglas básicas de precache y runtime.
  2. Registrar el service worker desde el front-end mediante un script encolado en WordPress.
  3. Asegurarse de que el archivo se sirve desde la raíz (copiar manualmente o usar plugin/despliegue automatizado).
  4. Probar en Chrome DevTools y ajustar estrategias de cache según necesidades.
  5. Usar build (workbox-build / webpack) para proyectos con cambios frecuentes y gestión automática del precache manifest.

Ejemplo rápido: checklist de archivos

service-worker.js Archivo en la raíz con código Workbox
js/sw-register.js Script encolado en WordPress que registra el SW
functions.php Encola el script de registro
plugin opcional Copia/actualiza el service-worker.js en la raíz al activar

Con estas instrucciones tienes todo lo necesario para implementar un service worker básico con Workbox en WordPress, desde la opción rápida usando el CDN hasta la integración con un flujo de build profesional. Ajusta las rutas, nombres y políticas de cache según tu proyecto.



Acepto donaciones de BAT's mediante el navegador Brave 🙂



Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *