islamalsayed / laravel-toasts
Modern, elegant toast notifications and confirmation dialogs for Laravel with full Livewire 3.x support, emoji integration, and RTL compatibility
Installs: 9
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/islamalsayed/laravel-toasts
Requires
- php: ^8.0
- illuminate/support: ^10.0 || ^11.0 || ^12.0
Requires (Dev)
- orchestra/testbench: ^8.0 || ^9.0
- phpunit/phpunit: ^10.0
README
A modern, elegant, and powerful Laravel package for toast notifications and confirmation dialogs with full Livewire support.
โจ Features
- ๐จ Multiple toast types: Success โ , Error โ, Danger โ, Warning โ ๏ธ, Info โน๏ธ
- ๐ท๏ธ Two display modes: Standard (with titles) and Message-only (without titles)
- ๐ญ Custom icons & emojis with Font Awesome support
- ๐ Pin support for persistent notifications
- โฑ๏ธ Configurable duration and display positionsุด
- ๐ RTL/LTR support with full Arabic compatibility
- ๐ฏ Livewire 3.x integration with event dispatching
- โก JavaScript API for client-side notifications
- ๐ฌ Smooth animations with customizable timing
- ๐ Action buttons with custom callbacks
- ๐ก๏ธ Interactive confirmation dialogs
- ๐งช Fully tested with PHPUnit
- ๐ฆ Easy installation with granular asset publishing
๐ RTL & Arabic Support
All features work perfectly with Arabic text and RTL direction.
RTL
LTR
๐ฆ Installation
1. Install via Composer
composer require islamalsayed/laravel-toasts
2. Publish Assets
# Publish everything (recommended for first-time setup) php artisan vendor:publish --tag=toast-all # Or publish components individually: php artisan vendor:publish --tag=toast-config # Configuration file php artisan vendor:publish --tag=toast-views # Blade templates php artisan vendor:publish --tag=toast-css # CSS styles php artisan vendor:publish --tag=toast-js # JavaScript files php artisan vendor:publish --tag=toast-webfonts # Font Awesome fonts
3. Inject Toast View
Run the inject command to add the toast component to your master layout:
php artisan toasts:inject
This will automatically inject the following into your layout files:
- Blade snippet:
@include('vendor.toasts.toasts')in your<body>tag - CSS assets: FontAwesome and Toasts styles in
<head>or head.blade.php - JavaScript: Toasts scripts in
<head>or foot.blade.php
โ๏ธ Configuration
Environment Variables
Add these settings to your .env file:
# Animation timing TOASTS_MOVE=enable # Enable/disable toast movement TOASTS_ENTER_TIME=0.3s # Entry animation duration TOASTS_EXIT_TIME=0.3s # Exit animation duration TOASTS_VISIBLE_TIME=4s # How long toast stays visible TOASTS_START_DELAY_TIME=0.5s # Delay before showing toast # Confirmation defaults TOASTS_CONFIRM_PIN=true # Keep confirms pinned by default # Display settings TOASTS_DEFAULT_DIR=ltr # Text direction: ltr or rtl TOASTS_DEFAULT_POSITION=top # Toast position: top, right TOASTS_DEFAULT_THEME=info # Default theme: success, error, warning, info # Default messages TOASTS_DEFAULT_MESSAGE=Hello there! TOASTS_DEFAULT_TITLE=Notification # Confirmation texts TOASTS_CONFIRM_TITLE=Please Confirm TOASTS_CONFIRM_MESSAGE=Do you really want to proceed? TOASTS_CONFIRM_TEXT=Sure TOASTS_CANCEL_TEXT=Cancel
Configuration File
After publishing, customize config/toasts.php for more advanced settings.
๏ฟฝ๏ธ Artisan Commands
toasts:inject
Automatically injects toast component references into your layout files.
php artisan toasts:inject
What it does:
- Adds
@include('vendor.toasts.toasts')after<body>tag inmaster.blade.php - Adds CSS links (FontAwesome + Toasts) in
<head>section - Adds JavaScript module in footer or
<head>section - Creates proper comments for easy identification
Output:
Blade snippet injected into master.blade.php
CSS snippet injected into head.blade.php
JS snippet injected into foot.blade.php
Command Features:
- โ Smart pattern matching (handles various formatting styles)
- โ Safe operation (only removes toasts-related code)
- โ Informative feedback (clear success/skip messages)
- โ Clean output (removes extra blank lines)
- โ
Non-destructive (can be reversed with
toasts:inject)
๏ฟฝ๐ Basic Usage
Simple Toasts
// Using helper functions showToastSuccess('User created successfully!'); showToastError('Failed to delete item'); showToastWarning('Please check your input'); showToastInfo('New update available'); // Generic helper showToast('success', 'Operation completed!');
Message-Only Toasts (Without Titles)
For cleaner, minimal toasts without type titles, use the message variants:
// Success message without "Success" title showToastSuccessMessage('User created successfully!'); // Error message without "Error" title showToastErrorMessage('Failed to delete item'); // Danger message without "Danger" title showToastDangerMessage('Critical error occurred!'); // Warning message without "Warning" title showToastWarningMessage('Please check your input'); // Info message without "Info" title showToastInfoMessage('New update available');
Difference between standard and message variants:
// Standard toast (with title) showToastSuccess('User created!'); // Displays: [โ Success] User created! // Message-only toast (no title) showToastSuccessMessage('User created!'); // Displays: [โ ] User created!
With Session Flash
// Automatic toast from session flash return redirect()->back()->with('success', 'Data saved!'); return redirect()->route('dashboard')->withError('Access denied'); // All these work automatically: session()->flash('success', 'Item created!'); session()->flash('error', 'Validation failed!'); session()->flash('warning', 'Action required!'); session()->flash('info', 'Did you know?');
Using Toast Facade
use IslamAlsayed\LaravelToasts\Facades\Toast; Toast::success('Record saved!'); Toast::error('Something went wrong')->icon('bomb'); Toast::warning('Check your email')->emoji('๐ง'); Toast::info('System maintenance at 10PM')->pin();
โจ Advanced Usage
Chaining Methods
showToast('success', 'User profile updated!') ->title('Success') // Custom title ->emoji('๐') // Add emoji (replaces icon) ->icon('user-check') // Font Awesome icon ->pin() // Make sticky (won't auto-hide) ->duration('5s') // Custom duration (2s, 500ms, 1m) ->position('top') // Position: top, right ->dir('rtl') // Direction: rtl or ltr ->theme('success'); // Theme: success, error, warning, info
With Action Buttons
showToast('info', 'New message received') ->title('Notification') ->emoji('๐ฌ') ->withAction('View', route('messages.show', 1)) ->withAction('Mark as Read', '/messages/1/read'); Toast::warning('Unsaved changes detected') ->withAction('Save Now', '/save') ->withAction('Discard', '/discard') ->pin();
Confirmation Dialogs
// Simple confirmation addConfirm('Are you sure you want to delete this?'); // Advanced confirmation addConfirm('Permanently delete this user?') ->title('Confirm Deletion') ->emoji('โ ๏ธ') ->link(route('users.destroy', $user->id)) ->onConfirm('Yes, Delete') ->onCancel('Cancel') ->target('_self'); // Type-specific confirmations addConfirmSuccess('Save changes?'); addConfirmError('Delete permanently?'); addConfirmWarning('Overwrite existing file?'); addConfirmInfo('Mark all as read?');
๐ฏ Livewire Integration
Event Dispatching
Livewire components can dispatch toast events from the frontend:
// In your Livewire component <button wire:click="$dispatch('toast', { type: 'success',message: 'Action completed!' })"> Click Me </button> // With full options <button wire:click="$dispatch('toast', { type: 'warning', message: 'Are you sure?', title: 'Confirmation', emoji: 'โ ๏ธ', pin: true, duration: '3s' })"> Show Toast </button>
Using HandlesCrudSafely Trait
The package provides a trait for safe CRUD operations with automatic toast notifications:
namespace App\Livewire; use Livewire\Component; class Users extends Component { public function destroy($id) { // Default toast notification $user = User::find($id); if ($user) { $user->delete(); $this->dispatch('show-toast', [ 'type' => 'success', 'message' => 'Users deleted successfully.', 'title' => 'Success', 'emoji' => 'โ ' ]); } else { $this->dispatch('show-toast', [ 'type' => 'error', 'message' => 'Users not found.', 'title' => 'Error', 'emoji' => 'โ' ]); } } }
Complete Livewire Example
namespace App\Livewire; use Livewire\Component; use App\Models\User; class UserManager extends Component { public $name; public $email; public function save() { $this->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email|unique:users', ]); try { User::create([ 'name' => $this->name, 'email' => $this->email, ]); // Success toast showToast('success', 'User created successfully!') ->emoji('๐ค') ->title('Success') ->withAction('View Users', route('users.index')); $this->reset(['name', 'email']); } catch (\Exception $e) { // Error toast showToast('error', 'Failed to create user: ' . $e->getMessage()) ->emoji('โ') ->title('Error') ->pin(); } } public function render() { return view('livewire.user-manager'); } }
Livewire Blade Template
<div> <form wire:submit="save"> <input type="text" wire:model="name" placeholder="Name"> @error('name') <span class="error">{{ $message }}</span> @enderror <input type="email" wire:model="email" placeholder="Email"> @error('email') <span class="error">{{ $message }}</span> @enderror <button type="submit">Save User</button> </form> {{-- Dispatch toast from frontend --}} <button wire:click="$dispatch('show-toast', { type: 'info', message: 'Form ready for input', emoji: 'โน๏ธ' })"> Show Info </button> </div>
๐ฅ๏ธ JavaScript Usage
Browser Console
Test toasts directly in the browser console:
// Simple toast window.showToast({ type: "success", message: "It works!" }); // Advanced toast window.showToast({ type: "error", message: "Something went wrong", title: "Error", emoji: "๐ฅ", pin: true, duration: "5s", }); // Confirmation dialog window.showToastConfirm({ type: "warning", message: "Are you sure?", onconfirmLink: "/delete/123", title: "Confirm", emoji: "โ ๏ธ", onConfirm: "Yes", onCancel: "No", });
Custom JavaScript Events
// Dispatch from vanilla JavaScript document.getElementById('myButton').addEventListener('click', function() { window.showToast({ type: 'success', message: 'Button clicked!' emoji: '๐ฑ๏ธ', duration: '2s' }); }); // With Livewire Alpine.js <button @click="window.showToast({ type: 'info', message: 'Alpine works!', emoji: 'โก' })"> Click Me </button>
From External JavaScript Files
// In your app.js or custom script export function showSuccessToast(message) { window.showToast({ type: "success", message: message, title: "Success", emoji: "โ ", duration: "3s", }); } export function confirmDelete(url) { window.showToastConfirm({ type: "info", message: "Are you sure you want to delete this?", onconfirmLink: url, title: "Confirm Deletion", emoji: "๐๏ธ", onConfirm: "Delete", onCancel: "Cancel", }); }
Available Emojis:
// Success ->emoji('โ ') ->emoji('๐') ->emoji('๐') ->emoji('โ๏ธ') // Error ->emoji('โ') ->emoji('โ') ->emoji('๐ซ') ->emoji('๐ฅ') // Warning ->emoji('โ ๏ธ') ->emoji('โก') ->emoji('๐') ->emoji('๐ข') // Info ->emoji('โน๏ธ') ->emoji('๐ก') ->emoji('๐') ->emoji('๐') // Delete ->emoji('๐๏ธ') ->emoji('๐ฎ') ->emoji('โ') // Actions ->emoji('๐๏ธ') ->emoji('โ๏ธ') ->emoji('๐') ->emoji('๐พ')```
Real-World Examples:
Example 1: After creating a record
public function store(Request $request) { $user = User::create($request->all()); showToast('success', 'User created successfully!') ->title('Success') ->emoji('๐ค') ->withAction('View Profile', route('users.show', $user->id)); return redirect()->route('users.index'); }
Example 2: Before deleting (your current use case)
public function destroy($id) { // Default toast notification $user = User::find($id); if ($user) { $user->delete(); $this->dispatch('show-toast', [ 'type' => 'success', 'message' => 'Users deleted successfully.', 'title' => 'Success', 'emoji' => 'โ ' ]); } else { $this->dispatch('show-toast', [ 'type' => 'error', 'message' => 'Users not found.', 'title' => 'Error', 'emoji' => 'โ' ]); } }
Example 3: Livewire component
public function save() { $this->validate(); User::create($this->form); showToast('success', 'User added!') ->emoji('๐ฏ') ->title('Added') ->pin(); }
Example 4: Multiple toasts at once
public function import() { $success = 10; $failed = 2; if ($success > 0) { showToast('success', "$success items imported successfully") ->emoji('โ ') ->duration(3000); } if ($failed > 0) { showToast('warning', "$failed items failed to import") ->emoji('โ ๏ธ') ->withAction('View Log', '/import/log'); } }
Example 5: Using message-only helpers for cleaner notifications
public function updateProfile(Request $request) { $user = auth()->user(); $user->update($request->all()); // Clean message without "Success" title showToastSuccessMessage('Profile updated successfully!'); return redirect()->back(); } public function validateForm($data) { if (empty($data['email'])) { // Clean error without "Error" title showToastErrorMessage('Email is required'); return false; } if (!filter_var($data['email'], FILTER_VALIDATE_EMAIL)) { // Clean warning without "Warning" title showToastWarningMessage('Please enter a valid email address'); return false; } // Clean info without "Info" title showToastInfoMessage('Validation passed'); return true; } public function sendNotification() { try { // Send notification logic // Success with title for important actions showToastSuccess('Notification sent to all users!') ->emoji('๐ง') ->pin(); } catch (\Exception $e) { // Danger message for critical errors showToastDangerMessage('Failed to send notification: ' . $e->getMessage()); } }
๐งช Testing
Running Tests
# Run all tests composer test # Run specific test file vendor/bin/phpunit tests/Feature/ToastFeatureTest.php # Run with coverage composer test-coverage
Unit Tests Example
namespace IslamAlsayed\LaravelToasts\Tests\Unit; use IslamAlsayed\LaravelToasts\ToastFactory; use IslamAlsayed\LaravelToasts\Tests\TestCase; class ToastFactoryTest extends TestCase { public function test_can_create_success_toast() { $toast = ToastFactory::success('User created!'); $this->assertEquals('success', $toast->type); $this->assertEquals('User created!', $toast->message); } public function test_can_chain_methods() { $toast = ToastFactory::error('Failed!') ->title('Error') ->emoji('โ') ->pin() ->duration('5s'); $this->assertEquals('Error', $toast->title); $this->assertEquals('โ', $toast->emoji); $this->assertTrue($toast->pin); $this->assertEquals('5s', $toast->duration); } public function test_can_add_actions() { $toast = ToastFactory::info('New message') ->withAction('View', '/messages') ->withAction('Dismiss', '#'); $this->assertCount(2, $toast->actions); $this->assertEquals('View', $toast->actions[0]['label']); $this->assertEquals('/messages', $toast->actions[0]['url']); } }
Feature Tests Example
namespace IslamAlsayed\LaravelToasts\Tests\Feature; use IslamAlsayed\LaravelToasts\Tests\TestCase; use Illuminate\Foundation\Testing\RefreshDatabase; class ToastFeatureTest extends TestCase { use RefreshDatabase; public function test_toast_is_added_to_session() { showToastSuccess('Test message'); $toasts = session('toasts'); $this->assertNotNull($toasts); $this->assertCount(1, $toasts); $this->assertEquals('success', $toasts[0]->type); $this->assertEquals('Test message', $toasts[0]->message); } public function test_multiple_toasts_can_be_queued() { showToastSuccess('First'); showToastError('Second'); showToastWarning('Third'); $toasts = session('toasts'); $this->assertCount(3, $toasts); } public function test_redirect_with_flash_creates_toast() { $response = $this->get('/test-redirect'); $response->assertSessionHas('success', 'Operation completed!'); } }
Testing Livewire Integration
namespace Tests\Feature\Livewire; use App\Livewire\UserManager; use Livewire\Livewire; use Tests\TestCase; class UserManagerTest extends TestCase { public function test_success_toast_on_user_creation() { Livewire::test(UserManager::class) ->set('name', 'John Doe') ->set('email', 'john@example.com') ->call('save') ->assertDispatched('toast'); $toasts = session('toasts'); $this->assertNotNull($toasts); $this->assertEquals('success', $toasts[0]->type); } public function test_error_toast_on_validation_failure() { Livewire::test(UserManager::class) ->set('name', '') ->set('email', 'invalid-email') ->call('save') ->assertHasErrors(['name', 'email']); } }
๐ RTL & Arabic Support
All features work perfectly with Arabic text and RTL direction.
๐งฉ API Reference
Toast Properties
public $type; // success, error, info, warning public $message; // Toast message text public $title; // Optional toast title public $emoji; // Emoji next to title public $icon; // Font Awesome icon name public $duration; // Display duration (e.g., 2s, 500ms, 1m) public $position; // Position: top, right public $pin; // If true, toast remains until manually closed public $theme; // Theme color: success, error, etc. public $dir; // Text direction: ltr or rtl public $confirm; // Confirm button label public $cancel; // Cancel button label public $actions; // Array of actions [label + url]
Helper Functions
Standard Toast Helpers (With Titles)
| Function | Description |
|---|---|
showToast($type, $message) |
Create a generic toast |
showToastSuccess($message) |
Create success toast with title |
showToastError($message) |
Create error toast with title |
showToastDanger($message) |
Create danger toast with title |
showToastWarning($message) |
Create warning toast with title |
showToastInfo($message) |
Create info toast with title |
Message-Only Helpers (Without Titles)
| Function | Description |
|---|---|
showToastSuccessMessage($message) |
Success toast without "Success" title |
showToastErrorMessage($message) |
Error toast without "Error" title |
showToastDangerMessage($message) |
Danger toast without "Danger" title |
showToastWarningMessage($message) |
Warning toast without "Warning" title |
showToastInfoMessage($message) |
Info toast without "Info" title |
Confirmation Helpers
| Function | Description |
|---|---|
addConfirm($message) |
Create confirmation dialog |
addConfirmSuccess($message) |
Create success confirmation |
addConfirmError($message) |
Create error confirmation |
addConfirmWarning($message) |
Create warning confirmation |
addConfirmInfo($message) |
Create info confirmation |
Usage Example:
// With title (default) showToastSuccess('User created successfully!'); // Output: [โ Success] User created successfully! // Without title (message only) showToastSuccessMessage('User created successfully!'); // Output: [โ ] User created successfully! // Confirmation dialog addConfirmError('Delete this user?') ->link(route('users.destroy', $user->id)) ->onConfirm('Yes, Delete') ->onCancel('Cancel');
Facade Methods
use IslamAlsayed\LaravelToasts\Facades\Toast; Toast::success($message); Toast::error($message); Toast::warning($message); Toast::info($message); Toast::confirm($message);
Artisan Commands
| Command | Description |
|---|---|
toasts:inject |
Inject toast references into layout files |
Usage Examples:
# Initial setup - inject toasts into layouts
php artisan toasts:inject
๏ฟฝ Future Enhancements
- Toast queueing system (stacked notifications)
- Audio alerts on confirmations
- Persistent toasts across page reloads
- Built-in animation presets (slide, fade, bounce, zoom)
- Dark mode support
- Custom toast templates
- WebSocket integration for real-time notifications
๐ค Contributing
We welcome contributions! Here's how you can help:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Commit your changes:
git commit -m 'Add amazing feature' - Push to the branch:
git push origin feature/amazing-feature - Open a Pull Request
Development Setup
# Clone the repository git clone https://github.com/IslamAlsayed/laravel-toasts.git cd laravel-toasts # Install dependencies composer install # Run tests composer test
Code Style
This project follows PSR-12 coding standards. Please ensure your code adheres to these standards before submitting.
# Check code style composer phpcs # Fix code style composer phpcbf
๐ License
This package is open-sourced software licensed under the MIT license.
๐ฌ Support & Contact
- ๐ง Email: eslamalsayed8133@gmail.com
- ๐ผ LinkedIn: IslamAlsayed
- ๏ฟฝ Facebook: IslamAlsayed
- ๐ Issues: GitHub Issues
๐ Acknowledgments
- Built with โค๏ธ for the Laravel community
- Inspired by modern notification libraries
- Font Awesome for the amazing icons
๐ Changelog
See CHANGELOG.md for recent changes.
๐ Built for developers who want elegant, expressive, and flexible notifications in Laravel applications.






