Phara UI v2.x

Toast

A temporary notification that slides in from a screen corner, auto-dismisses after a configurable duration, and can be triggered from Alpine.js, JavaScript, or Livewire.

Setup

Place the component once in your layout file. It renders the toast container and registers the Alpine.js store.

Blade
{{-- resources/views/layouts/app.blade.php --}}
<body>
    {{ $slot }}

    {{-- Add before closing </body> --}}
    <x-ui::toast />
</body>
Types

Four types: success, warning, danger, and info (default). Each has a distinct icon and progress bar color.

Blade
{{-- Alpine.js --}}
<button @click="$store.toasts.add({ message: 'Changes saved successfully.', type: 'success' })">
    Success
</button>

<button @click="$store.toasts.add({ message: 'Your trial ends in 3 days.', type: 'warning' })">
    Warning
</button>

<button @click="$store.toasts.add({ message: 'Something went wrong.', type: 'danger' })">
    Danger
</button>

<button @click="$store.toasts.add({ message: 'Your report is being generated.', type: 'info' })">
    Info
</button>
With Title

Add a title for toasts that benefit from a heading alongside the message.

JavaScript
$store.toasts.add({
    title: 'Payment received',
    message: 'Invoice #1042 has been paid in full.',
    type: 'success',
})

$store.toasts.add({
    title: 'Access denied',
    message: 'You do not have permission to perform this action.',
    type: 'danger',
})
Persistent

Set duration to 0 to create a toast that stays until the user manually dismisses it. No progress bar is shown.

JavaScript
$store.toasts.add({
    title: 'New version available',
    message: 'Refresh the page to load v2.1.0.',
    type: 'info',
    duration: 0,
})
Custom Duration

Override the container's default duration per toast. The progress bar reflects the custom timing.

JavaScript
{{-- Quick (1.5 s) --}}
$store.toasts.add({ message: 'Copied to clipboard.', type: 'success', duration: 1500 })

{{-- Slow (10 s) --}}
$store.toasts.add({ message: 'Uploading file, please wait…', type: 'info', duration: 10000 })
Positions

Six screen positions. Set the position prop on the container in your layout. Top positions stack newest-first; bottom positions stack newest-last.

Blade
{{-- Bottom right (default) --}}
<x-ui::toast position="bottom-right" />

{{-- Bottom left --}}
<x-ui::toast position="bottom-left" />

{{-- Bottom center --}}
<x-ui::toast position="bottom-center" />

{{-- Top right --}}
<x-ui::toast position="top-right" />

{{-- Top left --}}
<x-ui::toast position="top-left" />

{{-- Top center --}}
<x-ui::toast position="top-center" />
Triggering

Three ways to fire a toast — Alpine.js store, the window.toast() shorthand, or a browser event from Livewire.

Blade
{{-- 1. Alpine.js store --}}
<button @click="$store.toasts.add({ message: 'Saved!', type: 'success' })">
    Save
</button>

{{-- 2. window.toast() shorthand --}}
<button onclick="window.toast('Saved!', 'success')">Save</button>
<button onclick="window.toast('Saved!', { type: 'success', title: 'Done', duration: 3000 })">Save</button>

{{-- 3. Browser event (from Livewire or vanilla JS) --}}

From a Livewire component method:

PHP
// In a Livewire component method:
$this->dispatch('toast', message: 'Profile saved!', type: 'success');
$this->dispatch('toast', message: 'Upload failed.', type: 'danger', title: 'Error');
$this->dispatch('toast', message: 'Processing in background…', type: 'info', duration: 0);