Search by

jeremykenedy / laravel-toast

jeremykenedy

Multi-framework toast notifications for Laravel with Tailwind, Bootstrap 5, Bootstrap 4, Blade, Livewire, Vue, React, and Svelte support.

Package info

github.com/jeremykenedy/laravel-toast

pkg:composer/jeremykenedy/laravel-toast

Statistics

Installs: 18

Dependents: 0

Suggesters: 0

Stars: 1

Open Issues: 0

v2.0.0 2026-09-11 09:38 UTC

README

Laravel Toast

Powerful, highly configurable toast notifications for Laravel with 49 animations,
19 per-toast props, RTL support, and dark mode.

Total Downloads Latest Stable Version Tests StyleCI License: MIT

Table of Contents

Framework Support

Blade + Alpine.js Livewire 3 / 4 Vue 3 React 18 Svelte 4
Tailwind v4
Bootstrap 5 🔧 🔧 🔧
Bootstrap 4 🔧 🔧 🔧

✅ Styled out of the box. All 49 animations, all 19 props, dark mode, and RTL, with the markup shipped for that CSS framework.

🔧 Works, but the markup is Tailwind. The Vue, React and Svelte components ship one Tailwind class map, so pairing them with Bootstrap gives you the right behavior with the wrong classes. Copy the component into your own source tree and restyle it:

cp vendor/jeremykenedy/laravel-toast/resources/js/vue/pages/ToastContainer.vue \
   resources/js/Components/ToastContainer.vue

The component's own ../../../css/toast-animations.css import will not resolve from your source tree, so point it at the package instead:

import '../../../vendor/jeremykenedy/laravel-toast/resources/css/toast-animations.css'

Adjust the depth to match where you put the file. Publishing the stylesheet with --tag=toast-css is only useful if you would rather @import it from your own CSS entry point; it does not fix the copied component's relative import.

Every combination shares the same ToastManager, the same payload, the same config and the same animations. The gap is styling only, and only for Bootstrap paired with a JavaScript frontend.

Requirements

  • PHP 8.2+
  • Laravel 10, 11, 12 or 13 (continuous integration covers 12 and 13)
  • One CSS framework: Tailwind v4, Bootstrap 5, or Bootstrap 4
  • One frontend: Blade + Alpine.js, Livewire 3 or 4, Vue 3, React 18, or Svelte 4
  • See Framework Support for which pairings ship styled

Installation

composer require jeremykenedy/laravel-toast
php artisan toast:install

Add to your layout before </body>:

@include('toast::toasts')

Or with the directive: @toasts

For Livewire: <livewire:toast-container />

Quick Start

// In any controller, service, or middleware
toast('Settings saved.');
toast('Upload failed.', 'error', 'Error');
toast('Heads up!', 'warning', null, 3000);

// Fluent chaining
toast()->success('Step 1 done.')->info('Starting step 2...');

// Facade
Toast::success('Created!');
Toast::error('Denied.', 'Access Error');

Existing flash messages work automatically:

return back()->with('success', 'Profile updated.');
// Displays as a success toast with no code changes

Choosing Your Frameworks

toast:install writes your choice to .env. You can also set it by hand:

TOAST_CSS=bootstrap5
TOAST_FRONTEND=livewire
Setting Values Default Effect
TOAST_CSS tailwind, bootstrap5, bootstrap4 tailwind Selects the view directory that renders
TOAST_FRONTEND blade, livewire, vue, react, svelte blade Records your setup for the install and switch commands

TOAST_FRONTEND does not select anything while rendering. Blade and Livewire resolve their own views, and the Vue, React and Svelte components are imported directly in your own code, so how you mount the toasts is already decided by what you import.

If you also run jeremykenedy/laravel-ui-kit, config('ui-kit.css_framework') keeps control so one switch still moves every package together. toast:install and toast:switch detect the kit and write UI_KIT_CSS rather than TOAST_CSS in that case, so toast is never pinned behind a later kit-wide switch. TOAST_CSS only takes over when you set it yourself.

Anything unrecognised falls back to tailwind and blade rather than failing to resolve a view.

Configuration

php artisan vendor:publish --tag=toast-config

Every config option is also an ENV variable and a per-toast prop override:

TOAST_CSS=tailwind
TOAST_FRONTEND=blade
TOAST_POSITION=top-right
TOAST_DIR=ltr
TOAST_DURATION=5000
TOAST_AUTO_DISMISS=true
TOAST_PAUSE_ON_HOVER=true
TOAST_STACK=true
TOAST_SHOW_ICONS=true
TOAST_SHOW_BORDER=true
TOAST_SHOW_CLOSE=true
TOAST_SHOW_PROGRESS=true
TOAST_PROGRESS_DIRECTION=rtl
TOAST_PROGRESS_POSITION=top
TOAST_OPACITY=1
TOAST_ENTER_ANIMATION=none
TOAST_ENTER_DURATION=0.5
TOAST_EXIT_ANIMATION=none
TOAST_EXIT_DURATION=0.5
TOAST_MAX_VISIBLE=5

Props Reference

All props work as global config defaults AND per-toast overrides.

Prop Default Options
position top-right top-left top-right top-center bottom-left bottom-right bottom-center
dir ltr ltr rtl
duration 5000 Milliseconds (0 = no auto-dismiss)
auto_dismiss true true false
pause_on_hover true true false
stack true true (accumulate) false (replace)
max_visible 5 Any integer
show_icon true true false
custom_icon null Raw SVG HTML string
show_border true true false
show_close true true false
show_progress true true false
progress_direction rtl rtl ltr
progress_position top top bottom
opacity 1 0 to 1
enter_animation none See Animations
enter_duration 0.5 Seconds
exit_animation none See Animations
exit_duration 0.5 Seconds

Per-Toast Override

toast()->success('Saved!', 'Done', 3000, [
    'position'           => 'bottom-right',
    'dir'                => 'rtl',
    'show_border'        => false,
    'show_close'         => false,
    'enter_animation'    => 'slide-right',
    'enter_duration'     => 0.3,
    'exit_animation'     => 'bounce-left',
    'exit_duration'      => 0.5,
    'progress_position'  => 'bottom',
    'opacity'            => 0.9,
]);

Animations

49 animation styles, plus none, available for both enter_animation and exit_animation. Every style ships an enter and an exit keyframe, and all of them work in every CSS framework and frontend. Directionless names (e.g., slide, bounce) use a sensible default (typically center or right):

Style Enter Exit
none Instant appear Instant remove
Fade
fade Fade in Fade out
fade-center Fade in (alias) Fade out (alias)
Slide
slide Slide in from right (default) Slide out to right (default)
slide-left Slide in from left Slide out to left
slide-right Slide in from right Slide out to right
slide-top Slide in from top Slide out to top
slide-bottom Slide in from bottom Slide out to bottom
Bounce
bounce Scale up, overshoot, settle (default) Scale up, overshoot, shrink (default)
bounce-left Overshoot from left then settle Bounce right then exit left
bounce-right Overshoot from right then settle Bounce left then exit right
bounce-top Overshoot from top then settle Bounce down then exit top
bounce-bottom Overshoot from bottom then settle Bounce up then exit bottom
bounce-center Scale up, overshoot, settle Scale up, overshoot, shrink
Shrink
shrink Scale up from center (default) Scale down to center (default)
shrink-left Expand from right edge Collapse toward right edge
shrink-right Expand from left edge Collapse toward left edge
shrink-top Expand from bottom edge Collapse toward bottom edge
shrink-bottom Expand from top edge Collapse toward top edge
shrink-center Scale up from center Scale down to center
Flip (3D)
flip Flip in 180 Y-axis (default) Flip out 180 Y-axis (default)
flip-left Flip in from right (Y-axis) Flip out to left (Y-axis)
flip-right Flip in from left (Y-axis) Flip out to right (Y-axis)
flip-top Flip in from bottom (X-axis) Flip out to top (X-axis)
flip-bottom Flip in from top (X-axis) Flip out to bottom (X-axis)
flip-center Flip in 180 (Y-axis) Flip out 180 (Y-axis)
Spin
spin Spin in + scale up (default) Spin out + scale down (default)
spin-left Spin in from left Spin out to left
spin-right Spin in from right Spin out to right
spin-top Spin in from top Spin out to top
spin-bottom Spin in from bottom Spin out to bottom
spin-center Spin in + scale up Spin out + scale down
Grow
grow Scale up from center (default) Scale down to center (default)
grow-left Scale up from right edge Scale down toward right edge
grow-right Scale up from left edge Scale down toward left edge
grow-top Scale up from bottom edge Scale down toward bottom edge
grow-bottom Scale up from top edge Scale down toward top edge
grow-center Scale up from center Scale down to center
Slam (overshoot)
slam Scale from 0, overshoot 120%, settle (default) Overshoot 115%, scale to 0 (default)
slam-left Fly in from left, overshoot 115%, settle Overshoot 115%, fly out left
slam-right Fly in from right, overshoot 115%, settle Overshoot 115%, fly out right
slam-top Fly in from top, overshoot 115%, settle Overshoot 115%, fly out top
slam-bottom Fly in from bottom, overshoot 115%, settle Overshoot 115%, fly out bottom
slam-center Scale from 0, overshoot 120%, settle Overshoot 115%, scale to 0
Wobble
wobble Wobble side-to-side then appear (default) Wobble side-to-side then disappear
wobble-left Wobble in from left Wobble then exit left
wobble-right Wobble in from right Wobble then exit right
wobble-top Wobble in from top Wobble then exit top
wobble-bottom Wobble in from bottom Wobble then exit bottom
wobble-center Wobble + scale up from center Wobble + scale down to center

Enter and exit animations have independent duration controls (enter_duration, exit_duration).

Animations Outside Blade

Blade and Livewire inline the keyframes for you, so there is nothing to wire up.

The Vue, React and Svelte components import the same stylesheet directly:

import '../../../css/toast-animations.css'

That resolves on its own when you import the component from the package:

import ToastContainer from '../../vendor/jeremykenedy/laravel-toast/resources/js/vue/pages/ToastContainer.vue'

If you copy the component into your own source tree instead, publish the stylesheet and point the import at it:

php artisan vendor:publish --tag=toast-css

Dark Mode

All three CSS frameworks support dark mode:

Tailwind v4 uses dark: variant classes automatically. No extra setup needed.

Bootstrap 5 uses text-bg-* classes that respect [data-bs-theme="dark"]. Add to your <html> tag:

<html data-bs-theme="dark"></html>

Bootstrap 4 uses inline styles for dark mode. The toast views detect .dark on the body class or prefers-color-scheme: dark media query.

Customizing Colors

Tailwind v4

Override toast colors via your app.css with theme accent variables or direct utility overrides:

/* Light mode */
.toast-success {
    @apply bg-emerald-50 text-emerald-900 border-emerald-300;
}
.toast-error {
    @apply bg-rose-50 text-rose-900 border-rose-300;
}

/* Dark mode */
.dark .toast-success {
    @apply bg-emerald-950 text-emerald-100 border-emerald-700;
}
.dark .toast-error {
    @apply bg-rose-950 text-rose-100 border-rose-700;
}

Or publish and edit the views directly:

php artisan vendor:publish --tag=toast-views
# Edit resources/views/vendor/toast/tailwind/blade/toasts.blade.php

Bootstrap 5

Override Bootstrap contextual colors in your stylesheet:

/* Light mode */
.toast.text-bg-success {
    background-color: #d1fae5 !important;
    color: #065f46 !important;
}
.toast.text-bg-danger {
    background-color: #fee2e2 !important;
    color: #991b1b !important;
}

/* Dark mode */
[data-bs-theme="dark"] .toast.text-bg-success {
    background-color: #064e3b !important;
    color: #d1fae5 !important;
}
[data-bs-theme="dark"] .toast.text-bg-danger {
    background-color: #7f1d1d !important;
    color: #fee2e2 !important;
}

Bootstrap 4

Override Bootstrap 4 alert colors:

/* Light mode */
.alert-success {
    background-color: #d1fae5;
    border-color: #6ee7b7;
    color: #065f46;
}
.alert-danger {
    background-color: #fee2e2;
    border-color: #fca5a5;
    color: #991b1b;
}

/* Dark mode */
.dark .alert-success,
@media (prefers-color-scheme: dark) {
    .alert-success {
        background-color: #064e3b;
        border-color: #047857;
        color: #d1fae5;
    }
}
.dark .alert-danger,
@media (prefers-color-scheme: dark) {
    .alert-danger {
        background-color: #7f1d1d;
        border-color: #b91c1c;
        color: #fee2e2;
    }
}

Usage

Facade

use Jeremykenedy\LaravelToast\Facades\Toast;

Toast::success('Saved.');
Toast::error('Failed.', 'Error');
Toast::warning('Low storage.');
Toast::info('Update available.');
Toast::clear();

HasToasts Trait

use Jeremykenedy\LaravelToast\Traits\HasToasts;

class UserController extends Controller
{
    use HasToasts;

    public function update(Request $request, User $user)
    {
        $user->update($request->validated());
        $this->toastSuccess('User updated.');
        return back();
    }
}

Livewire Events

// From any Livewire component
$this->dispatch('toast', message: 'Saved!', type: 'success');
$this->dispatch('toast-success', message: 'Created!');
$this->dispatch('toast-error', message: 'Failed!');

// With per-toast options
$this->dispatch('toast', message: 'RTL toast', type: 'info', options: [
    'dir' => 'rtl',
    'exit_animation' => 'slide-left',
]);

Vue / React / Svelte

Pass toasts via Inertia props or window.__toasts:

// Controller
return Inertia::render('Dashboard', [
    'toasts' => app(ToastManager::class)->get(),
]);
<!-- Or in Blade layout -->
<script>
    window.__toasts = @json(app(ToastManager::class)->get());
</script>

Changing Frameworks

After installation, use update or switch to change frameworks without losing configuration.

Update (Interactive)

The update command walks through framework selection with an interactive menu:

php artisan toast:update

Or pass options directly:

php artisan toast:update --css=bootstrap5 --frontend=vue
Option Values Description
--css tailwind, bootstrap5, bootstrap4 Change CSS framework
--frontend blade, livewire, vue, react, svelte Change frontend framework

Switch (Quick)

php artisan toast:switch --css=bootstrap5
php artisan toast:switch --frontend=livewire
php artisan toast:switch --css=tailwind --frontend=vue

After switching, run npm run build.

Artisan Commands

Command Description
toast:install Fresh install with interactive prompts. Detects existing installation.
toast:update Update framework selection interactively. Does not overwrite config.
toast:switch Quick framework switch via flags.

Install Options

Flag Description
--css= CSS framework: tailwind, bootstrap5, bootstrap4
--frontend= Frontend: blade, livewire, vue, react, svelte
--force Skip reinstall confirmation when already installed

Publishing Assets

php artisan vendor:publish --tag=toast-config
php artisan vendor:publish --tag=toast-views
php artisan vendor:publish --tag=toast-lang
php artisan vendor:publish --tag=toast-css
Tag Publishes to
toast-config config/toast.php
toast-views resources/views/vendor/toast/
toast-lang lang/vendor/toast/
toast-css resources/css/vendor/toast/toast-animations.css

Testing

composer test          # ./vendor/bin/pest --ci
composer lint          # ./vendor/bin/pint --test
composer format        # ./vendor/bin/pint

The suite has zero database dependencies. tests/TestCase.php forces SQLite :memory:, nullifies every real connection, and fails in setUp() if anything else is configured.

Livewire tests are grouped so the package can be verified without it installed:

./vendor/bin/pest --ci --exclude-group livewire

Contributing

See CONTRIBUTING.md. Security issues go through SECURITY.md, never a public issue.

Changelog

See CHANGELOG.md.

License

This package is open-sourced software licensed under the MIT license.