jeffersongoncalves/laravel-pwa-service-worker

A Laravel package that serves a PWA service worker at /sw.js from a Blade template whose cache version tracks the Vite build manifest hash. Ships precache + cache-first (hashed assets), network-first (navigations) and stale-while-revalidate (everything else) strategies with an offline fallback, all

Maintainers

Package info

github.com/jeffersongoncalves/laravel-pwa-service-worker

pkg:composer/jeffersongoncalves/laravel-pwa-service-worker

Fund package maintenance!

jeffersongoncalves

Statistics

Installs: 23

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v1.1.0 2026-06-22 00:00 UTC

This package is auto-updated.

Last update: 2026-06-23 11:50:05 UTC


README

Laravel PWA Service Worker

Laravel PWA Service Worker

Latest Version on Packagist GitHub Tests Action Status GitHub Code Style Action Status Total Downloads

Serve a production-ready PWA service worker at /sw.js, rendered from a Blade template whose cache version tracks the Vite build manifest hash — so a npm run build automatically busts the SW cache without you editing the worker.

Ships three caching strategies out of the box:

  • cache-first for content-hashed /build/* assets (immutable, safe to cache forever)
  • network-first for HTML navigations (fresh when online, cached + offline fallback when not)
  • stale-while-revalidate for everything else (images, fonts, …)

…plus precache on install, old-cache teardown on activate, and a pwa-updated postMessage so your front-end can show an "update available" toast.

Installation

composer require jeffersongoncalves/laravel-pwa-service-worker

The /sw.js route is registered automatically. Register the service worker from your layout:

<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js');
  }
</script>

Optionally publish the config and view:

php artisan vendor:publish --tag="pwa-service-worker-config"
php artisan vendor:publish --tag="pwa-service-worker-views"

Update notifications

When a new worker activates it postMessages { type: 'pwa-updated', version } to every controlled page. Listen for it to surface an "update available" prompt and reload once the user accepts:

<script>
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.register('/sw.js');

    let reloading = false;

    navigator.serviceWorker.addEventListener('message', (event) => {
      if (event.data?.type !== 'pwa-updated') {
        return;
      }

      // First install fires this too; only prompt when a worker was already
      // in control (i.e. this is a genuine upgrade, not the initial load).
      if (!navigator.serviceWorker.controller) {
        return;
      }

      if (window.confirm('A new version is available. Reload now?')) {
        window.location.reload();
      }
    });

    // Guard against reload loops if the SW takes control mid-session.
    navigator.serviceWorker.addEventListener('controllerchange', () => {
      if (reloading) {
        return;
      }
      reloading = true;
    });
  }
</script>

Offline fallback

The worker serves config('pwa-service-worker.offline_url') (default /offline) for a failed navigation when nothing is cached. You register that route — it is intentionally not provided, since the offline page is app-specific:

Route::view('/offline', 'offline')->name('pwa.offline');

Configuration

Key Default Description
enabled true Register the /sw.js route.
path sw.js Route path (keep at root for a / scope).
middleware [] Extra middleware applied to the /sw.js route (e.g. a security-headers middleware).
view pwa-service-worker::sw Blade view rendered as the worker body.
build_manifest public/build/manifest.json md5 seeds the cache version.
cache_prefix pwa Cache name is {prefix}-v{version}.
offline_url /offline Fallback for failed navigations.
precache_urls ['/offline', '/'] Seeded on install.
passthrough_prefixes ['/admin', '/livewire', '/api', …] Always hit the network.
passthrough_exact ['/sw.js', '/manifest.json'] Always hit the network (exact path).
asset_prefix /build/ Content-hashed assets served cache-first.

Testing

composer test

License

The MIT License (MIT). Please see License File for more information.