phil / pwa-bundle
An installable, offline-readable Symfony site without Workbox: a web application manifest from the configuration, a service worker served through AssetMapper with network-first and cache-first strategies, an offline page, a versioned precache list, and Stimulus controllers to install, update and pre
Package info
github.com/parler-haut-interagir-librement/pwa-bundle
Type:symfony-bundle
pkg:composer/phil/pwa-bundle
Requires
- php: >=8.5
- ext-mbstring: *
- ext-uri: *
- symfony/config: ^8.2
- symfony/dependency-injection: ^8.2
- symfony/http-foundation: ^8.2
- symfony/http-kernel: ^8.2
- symfony/routing: ^8.2
- twig/twig: ^3.21
Requires (Dev)
- phpunit/phpunit: ^13.4
- psr/log: ^3.0
- symfony/asset: ^8.2
- symfony/asset-mapper: ^8.2
- symfony/browser-kit: ^8.2
- symfony/css-selector: ^8.2
- symfony/dom-crawler: ^8.2
- symfony/framework-bundle: ^8.2
- symfony/stimulus-bundle: ^3.7
- symfony/translation: ^8.2
- symfony/twig-bridge: ^8.2
- symfony/twig-bundle: ^8.2
Suggests
- symfony/asset-mapper: To serve the service worker and the Stimulus controllers, and version the precached assets
- symfony/stimulus-bundle: For the controllers that register the worker and present a page on a second screen
- symfony/translation: For the offline page in English and French
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-11-13 22:46:38 UTC
README
An installable site that reads offline: a manifest generated from the configuration, a short service worker of its own served through AssetMapper, an offline page, and Stimulus controllers to install, update, go full screen and present on a second screen — no Workbox, no build step.
phil/pwa-bundle serves the web application manifest of the site at /manifest.webmanifest, written from the
configuration: names, identity, start and scope, display and display_override — full screen included —, colours,
language, icons versioned by AssetMapper, shortcuts and categories. Every member is checked when the container is
built.
It serves the service worker at /sw.js: a few lines of settings, then the code of the worker, a script of the
bundle served by AssetMapper at its versioned address. The worker caches a versioned precache list when it installs
— the offline page, the paths and assets of the configuration, those of other bundles —, deletes the caches of older
versions when it activates, answers navigations network-first with the offline page as a last resort, and
other requests cache-first, network-first or from the network alone by the prefix of their path. A page whose
Cache-Control says private or no-store is never kept.
A Stimulus controller registers the worker, offers to install the site when the browser does, offers to update it when a new worker waits, follows the connection, and enters or leaves the full screen. Another opens a page on a second screen with the Presentation API, or in a window of its own where the API is missing, and carries messages between both.
It is a Symfony bundle for AssetMapper and the Stimulus bundle; Webpack Encore is not supported.
Status
| Part | State |
|---|---|
| Manifest generated and checked from the configuration, icons versioned through the Asset component | Implemented and tested |
| Service worker of its own: precache, network-first and cache-first, offline page, versions, skip waiting | Implemented and tested |
/sw.js with its settings and importScripts() of the worker served by AssetMapper; safe headers and scope |
Implemented and tested |
| Precache providers for other bundles, by autoconfiguration | Implemented and tested |
Offline page and phil_pwa_head() |
Implemented and tested |
| Stimulus controller: register, install, update, connection, full screen | Implemented and tested |
| Stimulus controller: presentation on a second screen, with a fallback window | Implemented and tested |
| Fuzz target of the manifest reader | Implemented and tested |
| Flex recipe | Implemented |
| Browser test of installing and of reading offline, under Panther | Not started |
Documentation
| Document | What it covers |
|---|---|
| Installation | Requirements, installing, the layout and the controllers. |
| Configuration | Every option, with an example. |
| The manifest | Each member, what is checked, icons and shortcuts. |
| The service worker | Precache, strategies, offline, versions, headers, scope and CSP. |
| JavaScript | The Stimulus controllers: installing, updating, full screen, a second screen. |
| Integrations | What signage, an event programme or a kiosk builds on. |
| Extension points | The services to replace and when they are stable. |
| Testing | The bundle's PHP and JavaScript tests and its fuzz target. |
| Reference | Every class, service, route and Twig function of the bundle. |
Quick start
composer require phil/pwa-bundle
# config/packages/phil_pwa.yaml phil_pwa: manifest: name: Example short_name: Example theme_color: '#1b1b1b' background_color: '#ffffff' icons: - { src: images/icon-192.png, sizes: 192x192, type: image/png } - { src: images/icon-512.png, sizes: 512x512, type: image/png, purpose: [any, maskable] } service_worker: precache: [styles/app.css, /]
{# templates/base.html.twig #} <head> {{ phil_pwa_head() }} </head> <body {{ stimulus_controller('phil--pwa-bundle--pwa', {url: phil_pwa_service_worker_path(), scope: phil_pwa_scope()}) }}>
Requirements
PHP 8.5 or later with ext-mbstring and ext-uri, Symfony 8.2 or later and Twig 3.21; AssetMapper and the Stimulus
bundle for the worker and the controllers.
Contributing
Contributions are welcome on the PHIL monorepo: read the contribution guide and the code of conduct. Report a vulnerability privately, as the security policy explains, never in a public issue.
License
MIT, © Philippe Gamache, doing business as Le Gnome Archiviste; a Parler Haut Interagir Librement project. See LICENSE.