Transform your Pelican Panel into a full-fledged Progressive Web App. Users can install it like a native app and receive push notifications for all the important stuff.
- Installable PWA on desktop and mobile
- Generated
manifest.jsonandservice-worker.js - Service worker that prompts users when updates are available
- Push notifications (test push, routed notifications, and admin broadcast to all subscribers)
- Admin Sync Diagnostics block (overall status, usage, activity, queue/push readiness)
- VAPID key management via settings (with
.envfallback) - Localized UI strings (depends on panel locale)
- Complete admin settings page for everything PWA-related
- Recent Pelican Panel version
- HTTPS enabled (required for service workers and push)
- Browser with PWA support
- PNG icons for Android (SVG and ICO are not reliably supported for install icons or notifications)
minishlink/web-pushavailable in your Pelican install
- Download the plugin zip file
- Go to Admin → Plugins, click Import, and install
- Open Admin → PWA and configure settings
cd /var/www/pelican/plugins
# Upload and extract pwa-plugin hereIf minishlink/web-push wasn't installed automatically:
cd /var/www/pelican
composer require minishlink/web-push:^11.0.0 -WPush subscription endpoints must use HTTPS and resolve to public IP addresses.
Use these endpoints when another backend service needs to trigger a PWA push. They use Pelican's Application API authentication and rate limit.
- Enable push notifications in Admin > PWA and configure valid VAPID keys.
- Make sure users have subscribed to push in their profile. A push can only be sent to a user's registered browser subscriptions.
- Create a Pelican Application API key with Users: Write access. Send it as a bearer token in the
Authorizationheader. Keep this key secret and make requests over HTTPS.
Use your panel's public origin in place of https://panel.example.com. The user-specific endpoint takes the user's numeric panel ID.
curl --request POST 'https://panel.example.com/api/application/pwa/users/123/notifications' \
--header 'Authorization: Bearer YOUR_APPLICATION_API_KEY' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"title": "Server ready",
"body": "Your server has finished installing.",
"url": "/",
"tag": "server-ready"
}'Use the same headers and JSON body as the user-specific request, but call:
curl --request POST 'https://panel.example.com/api/application/pwa/notifications/broadcast' \
--header 'Authorization: Bearer YOUR_APPLICATION_API_KEY' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data '{
"title": "Scheduled maintenance",
"body": "The panel will be unavailable at 02:00 UTC.",
"url": "/",
"tag": "maintenance"
}'| Field | Type | Required | Meaning |
|---|---|---|---|
title |
string, up to 120 characters | Yes | Notification heading. |
body |
string, up to 300 characters | Yes | Notification text. |
url |
panel-relative path | No | Page opened when the notification is clicked. Must start with one /; defaults to /. |
icon |
string | No | Icon URL/path; defaults to the icon configured in Admin > PWA. |
badge |
string | No | Badge URL/path; defaults to the badge configured in Admin > PWA. |
tag |
string, up to 255 characters | No | Browser notification tag; defaults to pwa-api. |
require_interaction |
boolean | No | Ask the browser to keep the notification visible until the user interacts; defaults to false. |
On success, the response reports provider send results:
{
"message": "Push notification sent.",
"sent": 2,
"failed": 0,
"total": 2
}sent means the push service accepted the message. Browser and operating-system settings still determine whether it is displayed. The broadcast sends to all registered subscriptions and, like the existing admin broadcast, does not filter by notification preference channels.
| HTTP status | Meaning |
|---|---|
401 / 403 |
Missing or unauthorized Application API key, or insufficient Users: Write access. |
404 |
The target user or their subscriptions were not found; broadcast has no subscriptions. |
409 |
Push notifications are disabled in plugin settings. |
422 |
Invalid request fields. |
502 |
Subscriptions existed, but no push service accepted the message. Check the failed count. |
503 |
Plugin subscription migrations, Web Push library, or VAPID configuration are unavailable. |
Configure:
- Theme and background colors
- Start URL
- Cache settings (name and version)
- Manifest icons (192px and 512px PNG recommended)
- Apple touch icons for iOS (152px, 167px, 180px)
- Default icons for notifications and badges
- Push notification enablement and VAPID keys
All settings save to the database and fall back to your .env file if nothing is set.
Also includes a Sync Diagnostics showing:
- Overall status
- PWA users and active subscriptions
- Subscriptions per user
- Last push sent
- Last sync and last subscription refresh (server)
- Queue readiness and push stack readiness
Send a manual push to all active subscriptions. Fields include:
- Title and body
- Click URL
- Optional icon and badge overrides
Users get a PWA section in their profile with quick actions:
- Install PWA
- Request notification permissions
- Subscribe to push
- Unsubscribe from push
- Send test push
The profile also lists subscribed devices. Users can give each device a name, see its last push or subscription sync activity, and remove individual devices. Removing the current device also unsubscribes its browser from push notifications.
Android requires PNG icons — SVG and ICO files won't work reliably for app installation or notifications.
Place these in a publicly accessible location (e.g., public/):
/favicon-192.png— app icon/favicon-512.png— higher-res version/favicon-96.png— notification badge- Apple touch icons at 152px, 167px, and 180px (optional, for custom iOS icons)
Then enter the paths in Admin → PWA.
Using realfavicongenerator.net is the quickest option. Or with ImageMagick:
cd /var/www/pelican/public/
convert logo.png -resize 192x192 favicon-192.png
convert logo.png -resize 512x512 favicon-512.png
convert logo.png -resize 96x96 favicon-96.png- Generate your VAPID keys
- Add
vapid_subject,vapid_public_key, andvapid_private_keyin Admin → PWA (or in.env) - Enable push notifications in Admin → PWA
- On a user device, allow notifications and click Subscribe to Push
- Use Send Test Push to verify everything is working
- Test push sends directly to the current user's active subscriptions
- Broadcast sends directly from the panel to all active subscriptions
- If subscriptions are stale, users may need to re-subscribe
- Open the panel in a browser
- Click the install icon in the address bar (⊕ or monitor icon), or go to the three-dot menu → Install [App Name]
- Confirm by clicking Install
The app will appear on your desktop, in the Start menu, or Applications folder.
- Open the panel in a mobile browser
- Wait for the install banner, or tap the three-dot menu and choose Install app or Add to Home screen
- On Samsung Internet: Add page to → Home screen
- Tap Install when prompted
The app will launch in full-screen mode like a native app.
- Open the panel in Safari
- Tap the Share button → Add to Home Screen
- Optionally rename, then tap Add
Note: iOS has limitations with PWAs. Push notifications and background sync are not supported, and installation must be done through Safari.
- Desktop: Right-click the app icon → Uninstall
- Android: Long-press → Uninstall (or via App info)
- iOS: Long-press → Remove App
PWA server-side errors are written through Laravel's standard logger, so they go to the same log destination configured for Pelican. Search the panel log for messages beginning with PWA to find failed push deliveries, missing push configuration, subscription problems, or settings diagnostics errors. Push delivery entries include the subscription and user IDs, provider status, and a short sanitized reason; they do not include the push endpoint or notification contents.
Browser and service-worker errors happen on the user's device and are not sent to the panel log. Check that browser's developer console for client-side issues.
- Confirm HTTPS is enabled
- Confirm
/manifest.jsonand/service-worker.jsare accessible - Confirm icon paths are valid and point to PNG files
- Try clearing the browser cache
Android does not support SVG or ICO for app icons or notification badges. Switch to PNG.
- Verify browser notification permissions are granted
- Verify VAPID keys are configured correctly
- Verify
minishlink/web-pushis installed - Re-subscribe the device and run a test push
GNU General Public License v3.0