PWA for Craft CMS

Configuration

PWA keeps its configuration in two places. The manifest has its own screen, one per site. Everything else is under PWA → Settings, in four panes: General, Offline, Install prompt and Push. All of it is stored in project config, so it deploys with the rest of your site.

Where allowAdminChanges is off, the manifest, flight plan and settings screens are read-only, as Craft's own settings are: the values are shown, nothing can be saved, and a note says why. The actions that write the database rather than project config keep working there: Invalidate caches, Regenerate icons, and generating, verifying or rotating the VAPID keypair.

The manifest

PWA → Manifest, per site. Two sites on one install are two apps as far as a browser is concerned, with different scopes and start URLs and usually different names, so there is no shared manifest.

FieldDefaultNotes
Namethe site nameShown in the install dialog and the app switcher
Short namethe nameUnder the home-screen icon. Android truncates past twelve characters
Description—
Start URL/Relative to the site's base URL. Where a launch from the home screen lands. A full URL must be on the site's own origin
Scopethe site's base pathEverything outside it opens in a browser tab. A site at /de/ has a scope of /de/. Same origin only
DisplayStandaloneBrowser means an ordinary tab, and nothing will offer to install it
OrientationAny
App IDthe scopeThe app's stable identity, so changing the start URL does not create a second installed app. Same origin only
Theme colour#111827The title bar and task switcher
Background colour#ffffffThe launch screen. Match your page background
Icon source—One square PNG, JPEG or WebP image, 512px or larger. Everything else is generated from it. SVG is not accepted
Maskable icon—Optional pre-padded artwork for Android's adaptive icons. Without it, the source is inset to the 80% safe zone automatically

Images are stored by UID rather than element ID, so a manifest synced from development points at the same asset in production.

General

SettingDefaultWhy you would change it
EnabledonOff means no manifest, no worker, no injected tags
Manifest pathmanifest.webmanifestOnly if something else already answers at that path
Service workeronOff serves a manifest with no worker. The site will not be installable
Service worker pathsw.jsKeep it at the web root: a worker can only control the directory it is served from
Inject automaticallyonOff, and you place the tags yourself with {{ pwa.head() }}
Never inject into—Path patterns, * allowed, for pages that should never get a worker attached
iOS status barDefaultBlack translucent draws the page under the status bar and clips layouts not designed for it
Generate iOS splash screensonTwenty-four images. Off if you do not care about the iOS launch screen
Record eventsonInstalls, launches and offline hits for the flight deck
Keep events for90 days

Offline

SettingDefaultNotes
The offline page (URI)the shipped fallbackPer site. Point it at a page of your own so the fallback looks like the site
Precache the essentialsonThe offline page and the manifest icons, fetched when the worker installs
Also precache—Extra URLs fetched on install. Keep the list short
Pages / Assets / Images60 / 120 / 80How many responses each cache bucket holds before the oldest goes
Keep cached responses for30 daysAfter this a cached response is refetched rather than served

The caching rules themselves are the flight plan.

Install prompt

SettingDefaultNotes
Show the promptonOff leaves installation to the browser's own menu
Title, Bodythe manifest nameThe prompt's copy
Accept button, Dismiss buttonInstall, Not now
PositionBottom of the windowWhere you put it renders nothing until a template calls {{ pwa.installPrompt() }}
Delay10 secondsTime on the page before the prompt appears, once the browser has offered an install
Snooze after dismissal30 days
Show iOS visitors howonSafari never offers an install event, so iOS visitors get Share → Add to Home Screen instructions instead

Push (Pro)

SettingDefaultNotes
EnabledoffWhether visitors can subscribe
Contact address—A mailto: or https:// URL for the VAPID subject. Some push services reject messages without one
Default iconthe 192px icon
Badge—The monochrome silhouette Android shows in the status bar
Notify when an entry is publishedoffWith sections chosen, the first publish of an entry raises a broadcast
Devices per queue job100
Drop a device after3 failuresA 404 or 410 drops it immediately
Most devices250,000New subscriptions are refused once the list is this long. 0 means no limit. Setting: pushMaxSubscribers
New devices per minute300Across the whole site, on top of the per-address limit. Setting: pushNewPerMinute
Keep delivery records for30 days

The same pane holds Scheduled preflight: daily or weekly, the hour (and weekday) it runs, who the report is emailed to, and whether to email only when something fails. That is on by default.

See Web push for how subscribing and broadcasting work.

The config file

Any setting can be fixed in config/pwa.php, which takes precedence over what is saved in the control panel:

<?php

return [
    'injectExclude' => ['/print/*', '/embed/*'],
    'promptDelay' => 20,
    'cacheLifetimeDays' => 14,
    'preflightRecipients' => ['ops@example.com'],
];

Two settings exist only in the config file:

SettingDefault
extraPushHosts[]Push-service hosts to accept beyond the browsers' own. *.example.com matches subdomains. Config only, because the server POSTs to them
logLevelinfoVerbosity of storage/logs/pwa.log

Retention for preflight reports is auditRetentionDays, 180 by default.

Environment variables

Variable
PWA_VAPID_PUBLIC_KEYSupply your own VAPID keypair, as raw base64url or PEM.
PWA_VAPID_PRIVATE_KEYBoth must be set. They win over the stored keys.

Without them the keypair is generated on first use and stored in the database, never in project config. A private key in project config ends up in git.

Permissions

  • View the flight deck and preflight reports (pwa:view)
  • Manage the manifest and flight plan (pwa:manage)
  • Send push notifications (pwa:broadcast, Pro). It is a separate permission because a broadcast reaches people who are not on the site and cannot be recalled.

Settings are admin-only.