Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Pwa Laravel Package

samuelterra22/filament-pwa

Filament PWA adds progressive web app support to Filament panels, letting users install the admin as a standalone app with offline caching, manifest and service worker generation, plus customizable icons and theme colors via simple fluent configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

v1.0.0 is the first stable tag (the compare link against v0.0.0 ships with no changelog body), so treat this as the baseline API rather than an upgrade: nothing to migrate, but also nothing documented as "fixed" — pin the version and read the README once before wiring it into anything user-facing.

Minimal path:

  1. composer require samuelterra22/filament-pwa
  2. Publish the config: php artisan vendor:publish --tag="filament-pwa-config" (check php artisan vendor:publish output if the tag differs in this release).
  3. Register the plugin on the panel you actually want installable — not on every panel:
use SamuelTerra\FilamentPwa\FilamentPwaPlugin;

public function panel(Panel $panel): Panel
{
    return $panel
        ->id('field')
        // ...
        ->plugin(FilamentPwaPlugin::make());
}
  1. Fill in config/filament-pwa.php: app name, short name, start_url, theme/background colours, display: standalone, and the icon set (at minimum 192×192 and 512×512 PNG, plus a maskable variant).
  2. php artisan optimize:clear then hard-reload the panel.

Where to look first: Chrome DevTools → Application → Manifest (validity + install criteria) and → Service Workers (registration state and scope). Lighthouse's PWA/installability audit is the fastest pass/fail check. If the manifest 404s or the worker never activates, stop there — nothing downstream matters.

First real use case: a Filament panel used by field staff on phones where the win is install-to-home-screen, a branded splash, and a friendly offline page instead of Chrome's dinosaur. That's achievable in an afternoon. Full offline data entry is not — see Gotchas.

Implementation Patterns

Scope the plugin to one panel. Filament apps commonly run admin + an app-facing panel. Only the app-facing one should be installable; enabling it on admin gives you a second install prompt and a second service worker fighting over scope.

Separate cache strategies by route class. The useful mental model is three buckets:

  • Precache — icons, compiled CSS/JS, splash screens. Immutable, hashed by Vite; safe to cache-first.
  • Network-first with offline fallback — panel pages you want readable when the connection drops.
  • Never cache — anything under /livewire/, login/logout, password reset, and any authenticated HTML response.

If the published service worker stub is editable, encode that explicitly rather than relying on a default. If it isn't, be conservative in config and verify with DevTools → Network that authenticated pages aren't served (from ServiceWorker).

Bundle the offline page with the panel's own theme so the fallback doesn't look like a foreign site. A Blade view published from the package and overridden in resources/views/vendor/... is the usual extension point.

Deployment pipeline. Every release that changes assets needs the service worker's cache name/version bumped, otherwise returning users keep the old shell. Make it part of the deploy script:

php artisan optimize:clear
php artisan filament:assets
# bump the SW cache version constant, or rely on the package's build step

If the package's worker calls skipWaiting() + clientsClaim(), users get the new shell on next navigation with no prompt — convenient, but it can swap the page out from under someone mid-form. If it doesn't, add an update-available toast and let the user refresh.

Install prompt as a Filament action. Capture beforeinstallprompt, stash the event, and surface it via a panel render hook or a user-menu action ("Install app"). On iOS Safari there's no such event — show a static "Share → Add to Home Screen" hint instead. Don't show the prompt on desktop Chrome unless the panel is genuinely desktop-viable.

Pair with Filament's SPA/navigate mode carefully. wire:navigate and a service worker both intercept navigation; test that back/forward and deep links to a cold-loaded panel still resolve, particularly when the network is throttled to Offline.

Gotchas and Tips

  • Scope is decided by the worker's URL, not the config. A worker served from /field/sw.js only controls /field/*. Registering from a deeper path silently narrows control. If the panel lives on a subdomain, that's cleaner; on a subpath, verify the Service-Worker-Allowed header or root-level serving.
  • sw.js and manifest.json must not be long-cached. A CDN or Cache-Control: max-age=31536000 on the worker means you can never ship an update. Exclude both paths from your cache rules and from Laravel's response caching middleware.
  • HTTPS is mandatory (localhost excepted). Staging on plain HTTP over a LAN IP will fail installability and look like a package bug.
  • Never cache authenticated HTML. A cache-first rule on panel pages will serve one user's rendered page to another on a shared device. This is the single highest-risk misconfiguration here.
  • Livewire requests must bypass the worker. POSTs and /livewire/update calls cached or replayed cause phantom validation errors and stale state.
  • Stale everything after deploy. The classic symptom: "the new button doesn't exist" from one user only. Reproduce with DevTools → Application → Storage → Clear site data, then decide whether the fix is a cache version bump or an update prompt.
  • Vite dev server + service worker. A worker left registered while npm run dev is running will serve production assets over your HMR session. Unregister during development, or scope the plugin's registration to app()->isProduction().
  • Config caching. php artisan config:cache bakes the manifest values in; editing config/filament-pwa.php on a cached production box appears to do nothing. Clear cache as part of every config change.
  • Debugging: chrome://serviceworker-internals for unregister/stop control, DevTools → Application → Cache Storage to inspect what's actually stored, and Lighthouse in an incognito window (extensions and existing registrations skew results).
  • Extension points worth knowing before you fork: published config, published service worker stub, published offline view, and any panel-level options on FilamentPwaPlugin::make(). Exhaust those before vendoring — the API is one major version old and will likely move.
  • Version risk: with an empty changelog at 1.0.0, there's no signal about what's stable vs. incidental. Constrain to ^1.0 in composer.json, and re-run the installability audit on every minor bump rather than assuming silence means no change.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource