monciego/laravel-pwa
Composer 安装命令:
composer require monciego/laravel-pwa
包简介
A PWA (Progressive Web App) for Laravel.
关键字:
README 文档
README
Turn your Laravel application into a Progressive Web App with offline support, install prompts, and a fully customizable manifest — all from one package.
Features
- 📱 Install Modal — A one-time modal prompt asking users to install your app
- 🔔 Install Banner — A sticky banner on subsequent visits, configurable to top or bottom
- ⏰ Dismiss Reminder — Dismiss the banner; it reappears after a configurable interval (default 1 day). Set to
0to show on every visit - 🖼️ Config-Driven Manifest — Auto-generated
manifest.jsonwith full PWA manifest support (icons, splash screens, shortcuts, screenshots, custom properties) - 📄 Offline Page — Custom offline fallback page
- 🛜 Service Worker — Pre-configured service worker for offline support
- 🍎 iOS Safari Support — Shows home screen instructions on iOS devices
- 🔒 Browser Guard — Gracefully skips everything on browsers without service worker support
- ⚡ Livewire Compatible — Works seamlessly with Livewire (
data-navigate-oncesupport) - 🖥️ Artisan Commands — Simple CLI commands to publish assets and regenerate the manifest
Requirements
- PHP >= 8.0
- Laravel 8.x – 13.x
Installation
composer require monciego/laravel-pwa
Laravel will auto-discover the service provider and facade.
Quick Start
Publish all PWA assets with a single command:
php artisan monciego:install-pwa
This publishes:
| Asset | Path | Tag |
|---|---|---|
| Config | config/pwa.php |
monciego:publish-pwa-config |
| Manifest | public/manifest.json |
monciego:publish-manifest |
| Offline page | public/offline.html |
monciego:publish-offline |
| Service worker | public/sw.js |
monciego:publish-sw |
| App logo | public/logo.png |
monciego:publish-logo |
| Icons | public/images/icons/*.png |
monciego:publish-icons |
Then generate the manifest from your config:
php artisan monciego:update-manifest
Add to Your Layout
Place these Blade directives in your layout file:
{{-- Inside <head> --}} @PwaHead {{-- Before closing </body> --}} @RegisterServiceWorkerScript
That's it! Reload your app and you'll see the install modal on supported browsers.
How the Install Flow Works
-
First visit — When the browser detects the app is installable, a modal appears:
┌───────────────────────────────┐ │ │ │ [App Icon] │ │ │ │ Install App │ │ │ │ Install this app for faster │ │ access, offline support, │ │ and a better experience. │ │ │ │ ┌─────────────────────────┐ │ │ │ Install │ │ │ └─────────────────────────┘ │ │ Maybe later │ │ │ └───────────────────────────────┘ -
Install — Triggers the browser's native install prompt
-
Maybe later — Modal disappears, replaced by a sticky banner at the top (or bottom) of the page:
┌──────────────────────────────────────────────────────────┐ │ Install this app for faster access, offline support, and │ │ a better experience. [Install] [Dismiss] └──────────────────────────────────────────────────────────┘ -
Dismiss — Hides the banner for a configurable period (default 1 day), then it reappears
-
App installed — Both modal and banner hide permanently
Note: The modal shows only once. After clicking "Maybe later," the banner takes over on all future visits.
iOS Safari
On iOS, the browser's native install prompt is not supported. Instead, the modal and banner display instructions guiding the user to tap the Share button and select Add to Home Screen.
Blade Directives
@PwaHead
Outputs PWA meta tags and install UI styles. Place inside <head>:
<!-- PWA --> <meta name="theme-color" content="#6777ef" /> <meta name="apple-mobile-web-app-capable" content="yes" /> <meta name="apple-mobile-web-app-status-bar-style" content="default" /> <meta name="apple-mobile-web-app-title" content="Your App Name" /> <meta name="mobile-web-app-capable" content="yes" /> <link rel="apple-touch-icon" href="http://localhost/logo.png" /> <link rel="manifest" href="http://localhost/manifest.json" /> <!-- PWA end --> <style> /* ... install UI styles ... */ </style>
@RegisterServiceWorkerScript
Outputs the install modal/banner HTML and the service worker registration script. Place before </body>.
Helper Function
pwa(); // Returns the PWAService instance
Facade
use PWA; PWA::headTag(); PWA::registerServiceWorkerScript();
Configuration
Publish the config to customize:
php artisan vendor:publish --tag=monciego:publish-pwa-config
Then edit config/pwa.php:
<?php return [ /* |-------------------------------------------------------------------------- | Install Button |-------------------------------------------------------------------------- | Set to false to disable the install modal and banner entirely. */ 'install-button' => true, /* |-------------------------------------------------------------------------- | Debug Mode |-------------------------------------------------------------------------- | When enabled, service worker registration logs appear in the console. */ 'debug' => env('APP_DEBUG', false), /* |-------------------------------------------------------------------------- | Livewire Support |-------------------------------------------------------------------------- | Set to true to add data-navigate-once to the script tag. */ 'livewire-app' => false, /* |-------------------------------------------------------------------------- | Banner Dismiss Interval (minutes) |-------------------------------------------------------------------------- | How many minutes before showing the banner again after dismissal. | Set to 0 to show on every visit. */ 'banner_interval' => 1440, // 1 day /* |-------------------------------------------------------------------------- | Banner Position |-------------------------------------------------------------------------- | Where to show the install banner: "top" or "bottom" */ 'banner_position' => 'top', /* |-------------------------------------------------------------------------- | Web App Manifest |-------------------------------------------------------------------------- | These values are used when generating manifest.json. | Run `php artisan monciego:update-manifest` after changing them. */ 'manifest' => [ 'name' => env('APP_NAME', 'My PWA App'), 'short_name' => env('APP_NAME', 'PWA'), 'description' => env('APP_DESCRIPTION', ''), 'lang' => 'en', 'dir' => 'ltr', 'start_url' => '/', 'scope' => '/', 'display' => 'standalone', 'orientation' => null, // Omitted from manifest when null 'theme_color' => '#6777ef', 'background_color' => '#ffffff', 'categories' => [], /* |-------------------------------------------------------------------------- | Icons |-------------------------------------------------------------------------- | Key each icon by its size. The package converts this format | to the standard manifest array automatically. */ 'icons' => [ '72x72' => [ 'path' => '/images/icons/icon-72.png', 'purpose' => 'any', ], '96x96' => [ 'path' => '/images/icons/icon-96.png', 'purpose' => 'any', ], '128x128' => [ 'path' => '/images/icons/icon-128.png', 'purpose' => 'any', ], '144x144' => [ 'path' => '/images/icons/icon-144.png', 'purpose' => 'any', ], '152x152' => [ 'path' => '/images/icons/icon-152.png', 'purpose' => 'any', ], '192x192' => [ 'path' => '/images/icons/icon-192.png', 'purpose' => 'any', ], '384x384' => [ 'path' => '/images/icons/icon-384.png', 'purpose' => 'any', ], '512x512' => [ 'path' => '/images/icons/icon-512.png', 'purpose' => 'any maskable', ], ], /* |-------------------------------------------------------------------------- | Splash Screens |-------------------------------------------------------------------------- */ 'splash' => [ '640x1136' => '/images/icons/splash-640x1136.png', '750x1334' => '/images/icons/splash-750x1334.png', '828x1792' => '/images/icons/splash-828x1792.png', '1125x2436' => '/images/icons/splash-1125x2436.png', '1242x2208' => '/images/icons/splash-1242x2208.png', '1242x2688' => '/images/icons/splash-1242x2688.png', '1536x2048' => '/images/icons/splash-1536x2048.png', '1668x2224' => '/images/icons/splash-1668x2224.png', '1668x2388' => '/images/icons/splash-1668x2388.png', '2048x2732' => '/images/icons/splash-2048x2732.png', ], 'shortcuts' => [], 'screenshots' => [], /* |-------------------------------------------------------------------------- | Custom Properties |-------------------------------------------------------------------------- | Any values defined here are merged into the generated manifest.json. */ 'custom' => [], ], ];
Updating the Manifest
After changing config values, regenerate the manifest:
php artisan monciego:update-manifest
This reads your config and writes a clean public/manifest.json with all icons properly formatted, null values stripped, and custom properties merged.
Icons
The icons config uses a keyed format ('192x192' => ['path' => '...']). The package automatically converts these to the standard manifest array on generation. The purpose field is optional — omit it or set it to 'any' and it won't appear in the output.
Place your icon files in public/images/icons/. To publish the default icons from the package:
php artisan vendor:publish --tag=monciego:publish-icons --force
Commands
| Command | Description |
|---|---|
php artisan monciego:install-pwa |
Publish all PWA assets (config, manifest, offline page, service worker, logo, icons) |
php artisan monciego:update-manifest |
Regenerate public/manifest.json from config/pwa.php |
Browser Support
| Browser | Install Prompt | Service Worker | Notes |
|---|---|---|---|
| Chrome (desktop + Android) | ✅ | ✅ | Full support |
| Edge | ✅ | ✅ | Full support |
| Samsung Internet | ✅ | ✅ | Full support |
| Opera | ✅ | ✅ | Full support |
| Firefox (desktop) | ❌ | ✅ | No install prompt, service worker supported |
| Firefox (Android) | ❌ | ✅ | No install prompt, service worker supported |
| Safari (macOS) | ❌ | ✅ | No install prompt |
| Safari (iOS) | ❌ | ✅ | Shows home screen instructions via Share menu |
| Older browsers | ❌ | ❌ | Everything is gracefully skipped |
On unsupported browsers, the package renders no event listeners and performs no storage operations — it exits silently.
Publishing Individual Assets
# Config only php artisan vendor:publish --tag=monciego:publish-pwa-config # Manifest only (static seed file) php artisan vendor:publish --tag=monciego:publish-manifest # Offline page only php artisan vendor:publish --tag=monciego:publish-offline # Service worker only php artisan vendor:publish --tag=monciego:publish-sw # Logo only php artisan vendor:publish --tag=monciego:publish-logo # Icons only (all sizes) php artisan vendor:publish --tag=monciego:publish-icons
Use --force to overwrite existing files.
Manual Logo Upload
The package includes a utility class for handling logo uploads via a controller:
use MonciegoLaravelPwa\LogoUploader; use Illuminate\Http\Request; public function uploadLogo(Request $request) { $result = LogoUploader::processLogo($request); if ($result['status']) { return back()->with('success', $result['message']); } return back()->withErrors($result['errors'] ?? $result['error']); }
The logo must be a 512x512 PNG, max 1MB.
Disabling the Install UI
Set 'install-button' => false in config/pwa.php. The meta tags and service worker will still work, but the install modal and banner won't render.
Testing the Install Flow
Clear localStorage items in your browser console to reset prompts:
localStorage.removeItem("pwa_maybe_later_clicked"); // Show modal again localStorage.removeItem("pwa_banner_dismissed_at"); // Reset banner dismiss timer
Running Tests
composer test
Security
If you discover any security-related issues, please email jerichobantiquete@gmail.com instead of using the issue tracker.
License
The MIT License (MIT). See LICENSE for details.
统计信息
- 总下载量: 0
- 月度下载量: 0
- 日度下载量: 0
- 收藏数: 0
- 点击次数: 0
- 依赖项目数: 0
- 推荐数: 0
其他信息
- 授权协议: MIT
- 更新时间: 2026-07-07