Skip to main content
Chapter 4 Blade Templating and Frontend Integration

Flash Messages and Dynamic UI

14 min read Lesson 17 / 28

Session Flash Messages and Interactive UI Patterns

Flash messages provide user feedback after form submissions. Combined with Alpine.js, you can build rich interactive UIs without heavy JavaScript.

Flash Messages in Controllers

// Success message
return redirect()->route('posts.index')
    ->with('success', 'Post created successfully.');

// Error message
return back()->with('error', 'Unable to process your request.');

Displaying Flash Messages

{{-- resources/views/partials/flash.blade.php --}}
@if(session('success'))
    <div x-data="{ show: true }"
         x-show="show"
         x-init="setTimeout(() => show = false, 5000)"
         x-transition:leave.duration.300ms
         class="bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded-lg">
        {{ session('success') }}
        <button @click="show = false" class="float-right">✕</button>
    </div>
@endif

@if(session('error'))
    <div class="bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded-lg">
        {{ session('error') }}
    </div>
@endif

Validation Error Display

{{-- Show all errors --}}
@if($errors->any())
    <div class="bg-red-50 p-4 rounded-lg">
        <ul class="list-disc pl-5">
            @foreach($errors->all() as $error)
                <li>{{ $error }}</li>
            @endforeach
        </ul>
    </div>
@endif

{{-- Per-field errors --}}
<input type="text" name="title"
       class="@error('title') border-red-500 @enderror"
       value="{{ old('title') }}">
@error('title')
    <p class="text-red-500 text-sm mt-1">{{ $message }}</p>
@enderror

Alpine.js Interactive Patterns

{{-- Dropdown --}}
<div x-data="{ open: false }" class="relative">
    <button @click="open = !open">Menu</button>
    <div x-show="open" @click.away="open = false"
         x-transition class="absolute mt-2 bg-white shadow-lg rounded-lg">
        <a href="#" class="block px-4 py-2">Profile</a>
        <a href="#" class="block px-4 py-2">Settings</a>
    </div>
</div>

{{-- Tabs --}}
<div x-data="{ tab: 'overview' }">
    <nav class="flex gap-4">
        <button @click="tab = 'overview'"
                :class="tab === 'overview' && 'border-b-2 border-brand-primary'">
            Overview
        </button>
        <button @click="tab = 'reviews'"
                :class="tab === 'reviews' && 'border-b-2 border-brand-primary'">
            Reviews
        </button>
    </nav>
    <div x-show="tab === 'overview'">Overview content</div>
    <div x-show="tab === 'reviews'">Reviews content</div>
</div>

These patterns give you interactive, modern UIs with minimal JavaScript complexity.