Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Webpush Laravel Package

laravel-notification-channels/webpush

Laravel notification channel for sending Web Push notifications. Supports VAPID keys, major browsers, rich payload options (title, actions, data, TTL), and easy subscription management on models with automatic cleanup of expired endpoints.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require laravel-notification-channels/webpush
    
  2. Add Trait to Model: Attach HasPushSubscriptions to your User (or any notifiable) model:

    use NotificationChannels\WebPush\HasPushSubscriptions;
    
    class User extends Model
    {
        use HasPushSubscriptions;
    }
    
  3. Publish Assets: Run migrations and config:

    php artisan vendor:publish --provider="NotificationChannels\WebPush\WebPushServiceProvider" --tag="migrations"
    php artisan vendor:publish --provider="NotificationChannels\WebPush\WebPushServiceProvider" --tag="config"
    php artisan migrate
    
  4. Generate VAPID Keys:

    php artisan webpush:vapid
    

    (Add VAPID_SUBJECT for Safari/iOS support, e.g., https://yourdomain.com)

  5. First Notification: Create a notification class:

    use NotificationChannels\WebPush\WebPushMessage;
    use NotificationChannels\WebPush\WebPushChannel;
    
    class AccountApproved extends Notification
    {
        public function via($notifiable) { return [WebPushChannel::class]; }
    
        public function toWebPush($notifiable, $notification) {
            return (new WebPushMessage)
                ->title('Approved!')
                ->body('Your account was approved!');
        }
    }
    

Where to Look First

  • Documentation: WebPushMessage for message options.
  • Config: config/webpush.php for customization (e.g., automatic_padding, default_encoding).
  • Events: NotificationSent/NotificationFailed for debugging.

Implementation Patterns

Core Workflow

  1. Frontend (Browser):

    • Register a service worker and call PushManager.subscribe().
    • Send subscription data (endpoint, keys.p256dh, keys.auth) to Laravel via API.
  2. Laravel Backend:

    • Save subscription to the user model:
      $user->updatePushSubscription($endpoint, $key, $token);
      
    • Send notifications via Laravel’s Notification facade:
      $user->notify(new AccountApproved());
      
  3. Notification Handling:

    • Use WebPushMessage for classic push or DeclarativeWebPushMessage for modern declarative syntax.
    • Customize with methods like ->icon('/icon.png')->action('View', 'action_id').

Integration Tips

  • Polymorphic Models: Use HasPushSubscriptions on any model (e.g., Team, Device) by configuring morph_map in config/webpush.php:

    'morph_map' => [
        'users' => \App\Models\User::class,
        'teams' => \App\Models\Team::class,
    ],
    
  • Batch Sending: Send to multiple users:

    Notification::send($users, new AccountApproved());
    
  • Dynamic Data: Pass custom data to the frontend:

    ->data(['order_id' => 123, 'status' => 'shipped'])
    
  • Declarative Messages: Use DeclarativeWebPushMessage for silent notifications or navigation:

    ->navigate('https://app.com/dashboard')
    ->silent()
    
  • Fallbacks: Combine with email/SMS in via():

    public function via($notifiable) {
        return [WebPushChannel::class, MailChannel::class];
    }
    
  • Testing: Mock subscriptions in tests:

    $user->updatePushSubscription('test_endpoint', 'test_key', 'test_token');
    

Gotchas and Tips

Pitfalls

  1. VAPID Keys:

    • Never regenerate keys in production (breaks existing subscriptions).
    • Safari/iOS Requirement: Missing VAPID_SUBJECT causes BadJwtToken errors. Use a valid domain (e.g., https://yourdomain.com).
  2. Subscription Expiry:

    • Expired subscriptions are auto-deleted on failed sends. Verify endpoints are active via:
      $user->pushSubscriptions()->where('endpoint', $endpoint)->exists();
      
  3. Browser Support:

    • Chrome/Firefox/Edge: Fully supported.
    • Safari: Requires VAPID_SUBJECT and may have limited features.
    • Mobile: Test on real devices (emulators may not support push).
  4. Payload Size:

    • Max payload size is ~4KB. Compress data or use external URLs for large payloads.
  5. Service Worker:

    • Ensure your frontend service worker handles push events and displays notifications:
      self.addEventListener('push', (event) => {
          event.waitUntil(
              self.registration.showNotification(event.data.json().title, {
                  body: event.data.json().body,
                  icon: event.data.json().icon,
              })
          );
      });
      

Debugging

  • Failed Notifications: Listen for NotificationFailed events:

    event(new NotificationFailed($user, $notification, $exception));
    

    Check exception->getMessage() for errors (e.g., InvalidVapidSignature).

  • Log Reports: Enable debug mode in config/webpush.php:

    'debug' => env('APP_DEBUG', false),
    
  • WebPush-PHP Logs: Set WP_LOG_LEVEL in .env:

    WP_LOG_LEVEL=debug
    

Extension Points

  1. Custom Report Handler: Extend ReportHandler to log failed sends:

    use NotificationChannels\WebPush\ReportHandler;
    
    class CustomReportHandler extends ReportHandler
    {
        public function handle($report) {
            Log::error('Push failed', ['report' => $report]);
            parent::handle($report);
        }
    }
    

    Register in config/webpush.php:

    'report_handler' => \App\Handlers\CustomReportHandler::class,
    
  2. Custom Message Class: Extend WebPushMessage for reusable templates:

    class AlertMessage extends WebPushMessage
    {
        public function __construct() {
            $this->icon('/alert-icon.png')
                 ->vibrate([200, 100, 200]);
        }
    }
    
  3. Dynamic VAPID Keys: Override getVapidKeys() in a custom service provider:

    public function register() {
        $this->app->bind('webpush.vapid', function () {
            return [
                'publicKey' => config('services.vapid.public_key'),
                'privateKey' => config('services.vapid.private_key'),
                'subject' => config('services.vapid.subject'),
            ];
        });
    }
    
  4. Migration Customization: Modify the migration table name/columns in config/webpush.php:

    'table' => 'push_subscriptions',
    'connection' => 'pgsql',
    

Pro Tips

  • Environment-Specific Keys: Use .env overrides for staging/production:

    VAPID_PUBLIC_KEY=staging_public_key
    VAPID_PRIVATE_KEY=staging_private_key
    
  • Rate Limiting: Throttle push sends to avoid browser throttling (e.g., 1 push/second per user).

  • A/B Testing: Use DeclarativeWebPushMessage for A/B testing notification styles without frontend changes.

  • Analytics: Track push open rates by including a campaign_id in data() and logging clicks via your service worker.

  • Fallback Icons: Provide multiple icon sizes in config/webpush.php:

    'default_icon' => [
        '192x192' => '/icons/icon192.png',
        '512x512' => '/icons/icon512.png',
    ],
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor