laravel 9 image upload with preview using tailwind css & alpine js

In this section we will see preview image before uploading using laravel with tailwind css & alpinejs. If you are start new project then you should install laravel breeze it come all three them. You can also read below article.

Preview Image Before Upload Alpine js with Tailwind CSS

Create Laravel Project

Run below command in your terminal to create laravel project.

composer create-project --prefer-dist laravel/laravel laravel-image  

Install laravel Breeze or setup laravel 9 with tailwind css alpine js.

Laravel 9 Authentication with Laravel Breeze

Create Blog Model Controller and routes

Run below command to create blog modal migration and controller.

 php artisan make:model Blog -mcr 


public function up()
    Schema::create('blogs', function (Blueprint $table) {



namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Blog extends Model
    use HasFactory;

    protected $fillable = [

Validate Image and store.



namespace App\Http\Controllers;

use App\Models\Blog;
use Illuminate\Http\Request;

class BlogController extends Controller
     * Display a listing of the resource.
     * @return \Illuminate\Http\Response
    public function index()
        $blogs = Blog::all();

        return view('blogs.index', compact('blogs'));

     * Show the form for creating a new resource.
     * @return \Illuminate\Http\Response
    public function create()
        return view('blogs.create');

     * Store a newly created resource in storage.
     * @param  \Illuminate\Http\Request  $request
     * @return \Illuminate\Http\Response
    public function store(Request $request)
            'title' => 'required|string|max:255',
            'content' => 'required',
            'image' => 'nullable|image|mimes:jpg,png,jpeg,gif,svg|max:2048'
        $image_path = '';
        if ($request->hasFile('image')) {
            $image_path = $request->file('image')->store('image', 'public');
            'title' => $request->title,
            'content' => $request->content,
            'image' => $image_path,
        return redirect()->route('blogs.index')->with('message', 'Blog Created Successfully');


Route::resource('blogs', BlogController::class);

Create Preview Image Before Uploading Laravel Tailwind CSS and AlpineJS

1. First you need to setup @stack('scripts') in your main blade file.


<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">

        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('', 'Laravel') }}</title>

        <!-- Fonts -->
        <link rel="stylesheet" href=";600;700&display=swap">
        <!-- Scripts -->
        @vite(['resources/css/app.css', 'resources/js/app.js'])


    <body class="font-sans antialiased">
        <div class="min-h-screen bg-gray-100">

            <!-- Page Heading -->
            <header class="bg-white shadow">
                <div class="px-4 py-6 mx-auto max-w-7xl sm:px-6 lg:px-8">
                    {{ $header }}

            <!-- Page Content -->
                {{ $slot }}


2. Next you need to add @push('scripts') in you blade file.


    <x-slot name="header">
        <h2 class="text-xl font-semibold leading-tight text-gray-800">
            {{ __('Blogs Create') }}

    <div class="py-12">
        <div class="mx-auto max-w-7xl sm:px-6 lg:px-8">
            <div class="overflow-hidden bg-white shadow-sm sm:rounded-lg">
                <div class="p-6 bg-white border-b border-gray-200">
                    <form method="POST" action="{{ route('') }}" enctype="multipart/form-data">
                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700 @error('title') text-red-500 @enderror">Title</span>
                                <input type="text" name="title"
                                    class="block @error('title') border-red-500 bg-red-100 text-red-900 @enderror w-full mt-1 rounded-md"
                                    placeholder="" value="{{old('title')}}" />
                            <div class="flex items-center text-sm text-red-600">
                                {{ $message }}

                        <div class="mb-6">
                            <label class="block">
                                <span class="text-gray-700 @error('content') text-red-500 @enderror">Content</span>
                                    class="block @error('content') border-red-500  bg-red-100 text-red-900 @enderror w-full mt-1 rounded-md"
                                    name="content" rows="3">{{old('content')}}</textarea>
                            <div class="flex items-center text-sm text-red-600">
                                {{ $message }}
                        <div class="mb-6">
                            <label class="block" x-data="showImage()">
                                <span class="sr-only">Choose File</span>
                                <input type="file" name="image" @change="showPreview(event)"
                                    class="block w-full text-sm text-gray-500 file:mr-4 file:py-2 file:px-4 file:rounded-full file:border-0 file:font-semibold file:bg-blue-50 file:text-blue-700 hover:file:bg-blue-100" />
                                <img id="preview" class="object-cover h-32 mt-2 w-60">
                            <div class="flex items-center text-sm text-red-600">
                                {{ $message }}

                        <button type="submit"
                            class="text-white bg-blue-600  rounded text-sm px-5 py-2.5">Submit</button>

        function showImage() {
            return {
                showPreview(event) {
                    if ( > 0) {
                        var src = URL.createObjectURL([0]);
                        var preview = document.getElementById("preview");
                        preview.src = src;
               = "block";
Laravel 9 Image Upload with Preview using Tailwind CSS & Alpine JS

Laravel 9 Image Upload with Preview using Tailwind CSS & Alpine JS

Read Also

Laravel 9 Add Simple Sidebar with Tailwind CSS Example

How to Use Carousel Slider in Laravel 9 Example

Laravel 9 Posts with Tags Many to Many Relationships Example

Laravel 9 Insert Category in Posts CRUD Example

How to Use Ckeditor 5 in Laravel 9 Vite with Tailwind CSS

Laravel 9 Simple Image Upload in Ckeditor 5 Example

Laravel 9 Flash Message Timeout and Hide Message Example

Install & Setup Markdown Editor in Laravel 9

Nuxt 3 Data Fetching Using Laravel 9 Api Example

Laravel 9 Image Upload with Preview using Tailwind CSS & Alpine JS

Laravel 9 with Tailwind CSS Form Validation Example

Laravel 9 Backend Api Connect with Vue 3 Using Axios Example

Laravel 9 Authentication with Next js Example

Laravel 9 Sanctum Authentication with Nuxt JS Example

Laravel 9 Simple Search with Pagination Example

Laravel 9 Install Setup TALL(Tailwind, Alpinejs, Livewire) Admin Panel

How to Fix and Clean Code Style in laravel 9

Laravel 9 Image File Upload Example

3 Way to Create Slug in Laravel 9 without Package

How to Add Dark Mode in Laravel 9 with Tailwind CSS