ovenlab / cakephp-pwa
Turn any CakePHP 5 application into an installable Progressive Web App: web manifest, service worker with configurable cache strategies, offline page, and VAPID web push notifications.
Requires
- php: >=8.1
- ext-gd: *
- ext-json: *
- ext-sodium: *
- cakephp/cakephp: ^5.0
- minishlink/web-push: ^9.0
Requires (Dev)
- cakephp/cakephp-codesniffer: ^5.0
- cakephp/migrations: ^4.0
- phpstan/phpstan: ^1.10
- phpunit/phpunit: ^10.1
README
Turn any CakePHP 5 application into an installable Progressive Web App: a web app manifest, a service worker with configurable caching strategies, an offline fallback page, and VAPID web push notifications — all wired through the familiar CakePHP plugin conventions.
Features
- Web app manifest — served dynamically at
/pwa/manifest.jsonand, after install, as a staticwebroot/manifest.json. - Service worker — configurable strategies (
network-first,cache-first,stale-while-revalidate,cache-only,network-only) with per-route overrides and a precache list. - Offline page — a fallback response at
/pwa/offlinefor navigations that fail while the user is offline. - Web push notifications — VAPID key generation, subscription persistence, and delivery via minishlink/web-push.
- Console commands — install, generate assets, generate the manifest and service worker, generate VAPID keys, and request cache clears.
- Middleware — PWA response headers plus optional security headers.
Requirements
- PHP >= 8.1 with the
json,sodium, andgdextensions - CakePHP >= 5.0
Installation
Install with Composer:
composer require ovenlab/cakephp-pwa
Load the plugin (in src/Application.php):
public function bootstrap(): void { parent::bootstrap(); $this->addPlugin('Pwa'); }
Or add it to config/plugins.php. Then run the interactive installer, which
creates config/pwa.php, generates VAPID keys, adds placeholder icons, injects
PWA meta tags into your default layout, and writes a static service worker and
manifest:
bin/cake pwa:install
Finally, run the migration to create the push_subscriptions table:
bin/cake migrations migrate -p Pwa
Configuration
The plugin reads config/pwa.php (copied from
config/pwa.example.php during pwa:install). All
values live under the Pwa key. Highlights:
return [ 'Pwa' => [ 'enabled' => true, 'name' => 'CakePHP PWA', 'short_name' => 'CakePWA', 'theme_color' => '#ffffff', 'icons' => [/* ... */], 'cache' => [ 'strategy' => 'network-first', 'version' => 'v1.0.0', 'routes' => [ '/css/*' => 'cache-first', '/api/*' => 'network-first', ], 'precache_files' => ['/', '/pwa/offline'], ], 'vapid' => [ 'public_key' => env('VAPID_PUBLIC_KEY'), 'private_key' => env('VAPID_PRIVATE_KEY'), 'subject' => env('VAPID_SUBJECT', 'mailto:admin@example.com'), ], ], ];
See Docs/Documentation/Configuration.md for the full reference.
Routes
All plugin routes are prefixed with /pwa and support the .json extension:
| Method | Route | Description |
|---|---|---|
| GET | /pwa/manifest |
Web app manifest (JSON) |
| GET | /pwa/service-worker |
Service worker script (JS) |
| GET | /pwa/offline |
Offline fallback page |
| GET | /pwa/config |
Runtime configuration inspector |
| GET | /pwa/push/vapid-key |
Public VAPID key (JSON) |
| POST | /pwa/push/subscribe |
Store a push subscription |
| POST | /pwa/push/unsubscribe |
Remove a push subscription |
| POST | /pwa/push/send |
Send a notification to all subscribers |
Push notifications
-
Generate VAPID keys (done automatically by
pwa:install, or manually):bin/cake pwa:generate-vapid-keys
-
In the browser, register the service worker and subscribe. The bundled
webroot/js/push.js(CakePWAPush) fetches the public key from/pwa/push/vapid-key, subscribes via the Push API, and POSTs the subscription to/pwa/push/subscribe. -
Send a notification from your app or from the console/HTTP:
curl -X POST https://example.com/pwa/push/send \ -H 'Content-Type: application/json' \ -d '{"title":"Hello","body":"World"}'
CSRF & authentication: the
/pwa/push/*endpoints are JSON APIs called from the browser, often without a CSRF token. Exempt/pwa/push/*from CSRF protection and, if you enforce auth globally, allow these routes. See Docs/Documentation/Security.md for copy-paste snippets.
Console commands
| Command | Description |
|---|---|
pwa:install |
Install and configure the plugin in the host app |
pwa:generate-assets |
Generate placeholder icons and screenshots (GD) |
pwa:generate-manifest |
Write a static webroot/manifest.json |
pwa:generate-sw |
Write a static webroot/sw.js |
pwa:generate-vapid-keys |
Generate VAPID keys into config/pwa.php |
pwa:clear-cache |
Request a client-side PWA cache clear |
Documentation
Full documentation lives in Docs/:
- Installation
- Configuration
- Service worker & caching
- Push notifications
- Customization
- Console commands
- Security
Testing
The plugin ships a standalone test suite that runs independently of any host app:
composer install composer test # phpunit composer cs-check # phpcs composer stan # phpstan
License
Released under the MIT License.