devrabiul/laravel-toaster-magic
Dependency-free toast notifications for Laravel with Livewire v3/v4 support. Drop-in, customizable toasts with multiple modern themes, RTL + dark mode, XSS-safe links, and no need for jQuery, Bootstrap, or Tailwind.
Installation:
composer require devrabiul/laravel-toaster-magic
php artisan vendor:publish --provider="Devrabiul\ToastMagic\ToastMagicServiceProvider"
(Assets auto-publish on first page load.)
Add to Blade:
<head>
{!! ToastMagic::styles() !!}
</head>
<body>
{!! ToastMagic::scripts() !!}
</body>
First Toast:
use Devrabiul\ToastMagic\Facades\ToastMagic;
ToastMagic::success('Success!', 'Your data has been saved.');
Trigger a success toast in a controller after a form submission:
public function store(Request $request) {
$request->validate([...]);
// Save data...
ToastMagic::success('Record Saved', 'Your changes have been successfully saved.');
return back();
}
Standard Toast Usage:
// Basic
ToastMagic::success('Title', 'Description');
// With options
ToastMagic::error('Error!', 'Something went wrong.', [
'showCloseBtn' => true,
'customBtnLink' => route('dashboard'),
]);
// Validation errors
ToastMagic::error($validator->errors());
Fluent Dispatch Pattern (for complex setups):
ToastMagic::dispatch()
->success('User Created', 'Profile saved successfully.')
->withOptions([
'timeOut' => 8000,
'theme' => 'material'
]);
Enable in config:
'livewire_enabled' => true,
'livewire_version' => 'v4', // or 'v3'
Dispatch from component:
$this->dispatch('toastMagic', [
'status' => 'success',
'title' => 'Updated!',
'message' => 'Your profile has been updated.',
'options' => ['customBtnText' => 'View Profile']
]);
Handle in JavaScript:
document.addEventListener('toastMagic', event => {
const { status, title, message, options } = event.detail;
toastMagic[status](title, message, options);
});
AJAX Responses:
axios.post('/api/endpoint')
.then(() => toastMagic.success('Success', 'Operation completed'))
.catch(() => toastMagic.error('Error', 'Failed to process request'));
Dynamic Theming:
// Switch theme based on user preference
const userTheme = localStorage.getItem('theme');
toastMagic.setTheme(userTheme || 'default');
Global Configuration:
// config/laravel-toaster-magic.php
'options' => [
'positionClass' => 'toast-bottom-end',
'theme' => 'glassmorphism',
'pauseOnHover' => true,
]
Theme Switching Middleware:
public function handle($request, Closure $next) {
if ($request->user()->prefers_dark_mode) {
ToastMagic::setTheme('neon');
}
return $next($request);
}
Custom Toast Component (for Blade):
@component('toast-magic::toast', [
'type' => 'info',
'title' => 'Notification',
'message' => 'This is a custom toast component'
])
@endcomponent
XSS Vulnerabilities:
// UNSAFE
ToastMagic::success('Hello, ' . $userInput);
// SAFE
ToastMagic::success('Hello, ' . e($userInput));
Duplicate Toasts:
preventDuplicates in config to avoid stacking identical toasts.Livewire Version Mismatch:
livewire_version in config matches your installed Livewire version (v3/v4).Session Flashing:
session()->flash() won't appear unless explicitly handled in your layout.Check Asset Loading:
ToastMagic::styles() and ToastMagic::scripts() are in the correct Blade positions.Console Errors:
toastMagic is not defined → Ensure scripts are loaded before DOM ready.Theme Conflicts:
Livewire Debugging:
dd($this->dispatch('toastMagic', [...]));
Per-Toast Overrides:
timeOut and showDuration in options override global config for that toast only.Position Classes:
toast-{position} (e.g., toast-custom-position).Dark Mode:
theme="dark" on <body> tag, not a config setting.Gradient Mode:
default, material, or neumorphism themes.Custom Themes:
resources/css/toast-magic.scss.JavaScript Hooks:
// Override default behavior
toastMagic.on('show', (toast) => {
console.log('Toast shown:', toast);
});
Livewire Event Filtering:
document.addEventListener('toastMagic', (e) => {
if (e.detail.status === 'warning') {
e.preventDefault();
// Custom handling for warnings
}
});
Vite Integration:
// config/laravel-toaster-magic.php
'use_vite' => env('APP_ENV') === 'local',
Disable Auto-Dismiss:
ToastMagic::success('Important', 'This toast stays until dismissed.', [
'timeOut' => 0
]);
Batch Processing:
const queue = [];
// ... process items ...
queue.forEach(item => {
toastMagic.success(`Processed ${item}`);
});
Lazy Loading:
@if(auth()->check())
{!! ToastMagic::scripts() !!}
@endif
Button Links:
http://, https://, /, and # URLs are sanitized by default.Message Content:
CSRF Protection:
Toast Stack Management:
// Clear all toasts
toastMagic.clear();
// Get current stack
console.log(toastMagic.getStack());
Dynamic Toast Types:
$status = $request->wasSuccessful() ? 'success' : 'error';
ToastMagic::$status('Operation Result', 'Details here.');
Conditional Toast Dispatch:
if ($this->shouldShowToast()) {
$this->dispatch('toastMagic', [
'status' => 'info',
'title' => 'Note',
'message' => 'This is a conditional toast.'
]);
}
Toast Templates:
@toastMagic
@slot('template')
<div class="custom-toast">
{{ $message }}
</div>
@endslot
How can I help you explore Laravel packages today?