Installation:
composer require mbarlow/megaphone
Publish the config and migrations:
php artisan vendor:publish --provider="Megaphone\MegaphoneServiceProvider" --tag="config"
php artisan vendor:publish --provider="Megaphone\MegaphoneServiceProvider" --tag="migrations"
php artisan migrate
Basic Integration:
Add the Livewire component to your layout (e.g., resources/views/layouts/app.blade.php):
<livewire:megaphone::bell />
Ensure your user model uses HasNotifications trait and implements routeNotificationFor():
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable
{
use Notifiable, HasNotifications;
public function routeNotificationFor($notification)
{
return $this->notifiable;
}
}
First Notification:
Create a notification class (e.g., app/Notifications/NewFeatureNotification.php):
use Megaphone\Notifications\Notification;
class NewFeatureNotification extends Notification
{
public function via($notifiable)
{
return ['database'];
}
public function toArray($notifiable)
{
return [
'title' => 'New Feature Available!',
'message' => 'Check out our latest updates.',
];
}
}
Trigger it for a user:
$user->notify(new NewFeatureNotification());
Admin Panel: Add the admin form to your admin dashboard:
<livewire:megaphone::admin-form />
Configure the admin route in config/megaphone.php:
'admin' => [
'route' => 'admin.notifications',
],
Notification Creation:
Extend Megaphone\Notifications\Notification for custom notifications. Override via() and toArray():
class CustomNotification extends Notification
{
public function via($notifiable)
{
return ['database', 'mail']; // Supports database, mail, slack, etc.
}
public function toArray($notifiable)
{
return [
'title' => 'Custom Title',
'message' => 'Custom message with {variable}',
'data' => ['key' => 'value'], // Optional extra data
];
}
}
Triggering Notifications:
$user->notify(new CustomNotification());
User::where('role', 'admin')->each(function ($user) {
$user->notify(new CustomNotification());
});
Reading Notifications: Users mark notifications as read via the bell component:
<livewire:megaphone::bell :user="$user" />
The component handles read/unread states automatically.
Customizing Admin Form:
Override the admin form view (resources/views/vendor/megaphone/admin-form.blade.php) to add custom fields:
<x-jet-form>
<x-slot name="form">
<div>
<x-jet-label for="title" value="Notification Title" />
<x-jet-input id="title" type="text" wire:model.defer="title" />
</div>
<div>
<x-jet-label for="message" value="Message" />
<x-jet-input id="message" type="textarea" wire:model.defer="message" />
</div>
<!-- Custom field -->
<div>
<x-jet-label for="custom_field" value="Custom Field" />
<x-jet-input id="custom_field" type="text" wire:model.defer="customField" />
</div>
</x-slot>
</x-jet-form>
Filtering Recipients:
Extend the admin form logic by overriding the users() method in a custom Livewire component:
namespace App\Http\Livewire;
use Megaphone\Http\Livewire\AdminForm;
class CustomAdminForm extends AdminForm
{
public function users()
{
return User::where('active', true)->get();
}
}
Update the admin form view to use your custom component:
<livewire:custom-admin-form />
Scheduling Notifications: Use Laravel's scheduling to delay notifications:
$schedule = now()->addMinutes(30);
Notification::create([
'title' => 'Scheduled Notification',
'message' => 'This will be sent later.',
'data' => ['scheduled_at' => $schedule],
]);
$this->dispatch(new SendScheduledNotifications($schedule));
Custom Notification Channels:
Megaphone supports Laravel's built-in notification channels (e.g., mail, database, slack). To add a custom channel:
// app/Providers/AppServiceProvider.php
use Megaphone\Notifications\Channels\CustomChannel;
public function boot()
{
Notification::extend('custom', function ($app) {
return $app->make(CustomChannel::class);
});
}
Use it in your notification:
public function via($notifiable)
{
return ['database', 'custom'];
}
Customizing Bell UI:
Override the bell component view (resources/views/vendor/megaphone/bell.blade.php) to modify the UI:
<div wire:click="toggle" class="relative">
<svg class="h-6 w-6 text-gray-800" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 17h5l-1.405-1.405A2.032 2.032 0 0118 14.158V11a6.002 6.002 0 00-4-5.659V5a2 2 0 10-4 0v.341C7.67 6.165 6 8.388 6 11v3.159c0 .538-.214 1.055-.595 1.436L4 17h5m6 0v1a3 3 0 11-6 0v-1m6 0H9" />
</svg>
@if ($unread > 0)
<span class="absolute top-0 right-0 inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-100 bg-red-500 rounded-full">{{ $unread }}</span>
@endif
</div>
Real-Time Updates: Use Laravel Echo and Pusher to update notifications in real-time:
// resources/js/app.js
import Echo from 'laravel-echo';
window.Pusher = require('pusher-js');
window.Echo = new Echo({
broadcaster: 'pusher',
key: process.env.MIX_PUSHER_APP_KEY,
cluster: process.env.MIX_PUSHER_APP_CLUSTER,
forceTLS: true,
});
Echo.channel('notifications')
.listen('NotificationSent', (data) => {
Livewire.emit('notificationSent', data);
});
Listen in your Livewire component:
protected $listeners = ['notificationSent' => 'refreshNotifications'];
public function refreshNotifications()
{
$this->emit('refresh');
}
Notification Not Appearing:
routeNotificationFor: Ensure your user model implements routeNotificationFor() correctly. For API users, return the API endpoint:
public function routeNotificationFor($notification)
{
return $this->notifiable ? 'https://your-app.com/api/notifications' : null;
}
database channel, ensure the notifications table exists and is accessible.php artisan queue:work to process notifications if using queues.Admin Panel Not Working:
auth, admin):
Route::middleware(['auth', 'admin'])->get('/admin/notifications
How can I help you explore Laravel packages today?