In this short tutorial, we will see how to implement session flash messages in Laravel with Inertia Vue 3. For this section, we will use Vue 3 Single File Components (SFCs) with the <script setup>
method.
CategoryController.php
public function store(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'slug' => 'required|string|max:255',
]);
Category::create([
'name' => $request->name,
'slug' => \Str::slug($request->slug)
]);
sleep(1);
return redirect()->route('category.index')->with('message', 'Category Created Successfully');
}
app/Http/Middleware/HandleInertiaRequests.php
<?php
namespace App\Http\Middleware;
use Illuminate\Http\Request;
use Inertia\Middleware;
use Tightenco\Ziggy\Ziggy;
class HandleInertiaRequests extends Middleware
{
/**
* The root template that is loaded on the first page visit.
*
* @var string
*/
protected $rootView = 'app';
/**
* Determine the current asset version.
*
* @param \Illuminate\Http\Request $request
* @return string|null
*/
public function version(Request $request)
{
return parent::version($request);
}
/**
* Define the props that are shared by default.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public function share(Request $request)
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user(),
],
'ziggy' => function () {
return (new Ziggy)->toArray();
},
'flash' => [
'message' => session('message')
]
]);
}
}
You need to add the flash message in the HandleInertiaRequests.php
shared data.
'flash' => [
'message' => fn () => $request->session()->get('message')
],
// Or
'flash' => [
'message' => session('message')
]
Category/Index.vue
<script setup>
import BreezeAuthenticatedLayout from "@/Layouts/Authenticated.vue";
import { Head } from "@inertiajs/inertia-vue3";
import BreezeButton from "@/Components/Button.vue";
import { Link } from "@inertiajs/inertia-vue3";
import { Inertia } from "@inertiajs/inertia";
defineProps({
categories: {
type: Object,
default: () => ({}),
},
});
function destroy(id) {
if (confirm("Are you sure you want to Delete")) {
Inertia.delete(route("category.destroy", id));
}
}
</script>
<template>
<Head title="Category" />
<BreezeAuthenticatedLayout>
<template #header>
<h2 class="text-xl font-semibold leading-tight text-gray-800">
Category
</h2>
</template>
<div class="py-12">
<div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
<!-- flash message start -->
<div
v-if="$page.props.flash.message"
class="p-4 mb-4 text-sm text-green-700 bg-green-100 rounded-lg dark:bg-green-200 dark:text-green-800"
role="alert"
>
<span class="font-medium">
{{ $page.props.flash.message }}
</span>
</div>
<!-- flash message end -->
<div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
<div class="p-6 bg-white border-b border-gray-200">
<div class="mb-2">
<Link :href="route('category.create')">
<BreezeButton>Add Category</BreezeButton></Link
>
</div>
<div
class="relative overflow-x-auto shadow-md sm:rounded-lg"
>
<table
class="w-full text-sm text-left text-gray-500 dark:text-gray-400"
>
<thead
class="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400"
>
<tr>
<th scope="col" class="px-6 py-3">#</th>
<th scope="col" class="px-6 py-3">
Category name
</th>
<th scope="col" class="px-6 py-3">
Slug
</th>
<th scope="col" class="px-6 py-3">
Created At
</th>
<th scope="col" class="px-6 py-3">
Edit
</th>
<th scope="col" class="px-6 py-3">
Delete
</th>
</tr>
</thead>
<tbody>
<tr
v-for="category in categories.data"
:key="category.id"
class="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
>
<th
scope="row"
class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap"
>
{{ category.id }}
</th>
<th
scope="row"
class="px-6 py-4 font-medium text-gray-900 dark:text-white whitespace-nowrap"
>
{{ category.name }}
</th>
<td class="px-6 py-4">
{{ category.slug }}
</td>
<td class="px-6 py-4">
{{ category.created_at }}
</td>
<td class="px-6 py-4">
<Link
:href="
route(
'category.edit',
category.id
)
"
class="px-4 py-2 text-white bg-blue-600 rounded-lg" >Edit</Link
>
</td>
<td class="px-6 py-4">
<BreezeButton
class="bg-red-600"
@click="destroy(category.id)"
>
Delete
</BreezeButton>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</BreezeAuthenticatedLayout>
</template>
You can also add flash message in main components.
<template>
<main>
<header></header>
<content>
<div v-if="$page.props.flash.message" class="alert">
{{ $page.props.flash.message }}
</div>
<slot />
</content>
<footer></footer>
</main>
</template>
Add category then see flash message.