Laravel 9 Upload Images with Spatie Media Library Tutorial Example

Throughout in this tutorial we are going to share Laravel image upload using Spatie media-library tutorial, Which will show us how to integrate the spatie media library in the laravel 9 application. Here we will learn how to use the Spatie media library for upload images files in the Laravel project step by step from scratch.

Spatie Media Library provide easily image uploading with laravel eloquent model. Using this package we can easily store images, get images, generate thumbnail images. laravel media-library in laravel to upload the image using Spatie can be implement in laravel 6, laravel 7, laravel 8 or laravel 9 apps.

Laravel Image Upload using Spatie Media Library Example

Follow the following steps to integrate laravel image upload using spatie media library;

  • Step 1: Install Laravel App
  • Step 2: Setup Database Details
  • Step 3: Install Spatie Medialibrary Package
  • Step 4: Create Model & Run Migration
  • Step 5: Create Controller File
  • Step 6: Add Routes
  • Step 7: Create Blade Files
  • Step 8: Add App URL
  • Step 9: Run Laravel App

Install Laravel App

First at all you need to install a latest version of the Laravel app, get to the terminal and execute the command.

composer create-project laravel/laravel spatie-upload-images --prefer-dist

Setup Database Details

Now update your database credentials database name, username, password in .env file:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db
DB_USERNAME=root
DB_PASSWORD=

Install Spatie Medialibrary in Laravel

Go to command line interface run command to install the laravel-medialibrary library.

composer require spatie/laravel-medialibrary

In this step, you have to run the vendor publish command.

php artisan vendor:publish --provider="Spatie\MediaLibrary\MediaLibraryServiceProvider" --tag="migrations"

Consequently, you have to execute a command to run migrations.

php artisan migrate

Create model and run migration

In this section, you need to execute command to create model and migration files.

php artisan make:model Post -m

In the migration, you have to define the value which will be added to the blogs table.

Update the app/database/migrations/create_posts_table.php file.

<?php
  
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
  
class CreatePostsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('posts', function (Blueprint $table) {
            $table->id();
            $table->string('title');
            $table->string('description');
            $table->timestamps();
        });
    }
  
    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('posts');
    }
}

Open app/Models/Post.php define the table value and add the Spatie media library modules.

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\MediaLibrary\InteractsWithMedia;
use Spatie\MediaLibrary\HasMedia;

class Post extends Model implements HasMedia
{
    use HasFactory, InteractsWithMedia;
    
    protected $fillable = [
        'title',
        'description',
    ];
}

Create Controller

Controllers help define the functions in relation to HTTP requests and other stuff; let us create a new controller.

php artisan make:controller PostController

After creating the controller open it and update the code into the app/Http/Controllers/PostController.php file.

<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Post;

class PostController extends Controller
{
    public function index()
    {    
        $posts = Post::latest()->get();
        return view('posts', compact('posts'));
    }
    public function create()
    {
        return view('media');
    }
    
    public function store(Request $request)
    {
        $input = $request->all();
        $post = Post::create($input);
        if($request->hasFile('image') && $request->file('image')->isValid()){
            $post->addMediaFromRequest('image')->toMediaCollection('image');
        }
        return redirect()->route('posts');
    }
}

Create Routes

Now, we have the controller placed, next we need routes to be added to routes/web.php file.

<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PostController;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
*/

Route::get('posts',[PostController::class,'index'])->name('posts');
Route::get('posts/create',[PostController::class,'create'])->name('posts.create');
Route::post('posts/store',[PostController::class,'store'])->name('posts.store');

Add Blade View Files

In the next section, you have to create blade templates one template will show the form for adding values, and the other template will show the list with the uploaded image.

Then, create and update app/resources/views/posts.blade.php file.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  
    <title>Laravel Image Upload with Spatie Medialibrary Example - ItSolutionstuff.com </title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
  
<body>
    <div class="container">
        <h1>Posts List</h1>
        <div class="d-flex p-2 bd-highlight mb-3">
            <a href="{{ route('posts.create') }}" class="btn btn-dark">Add</a>
        </div>
        <table class="table">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Title</th>
                    <th>Body</th>
                    <th width="30%">Image</th>
                </tr>
            </thead>
            <tbody>
                @foreach($posts as $key=>$post)
                <tr>
                    <td>{{ ++$key }}</td>
                    <td>{{ $post->title }}</td>
                    <td>{{ $post->body }}</td>
                    <td><img src="{{$post->getFirstMediaUrl('images', 'thumb')}}" / width="120px"></td>
                </tr>
                @endforeach
            </tbody>
        </table>
    </div>
</body>
  
</html>

Then, create and insert the code in the app/resources/views/media.blade.php file.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
  
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
  
    <title>Laravel Image Upload with Spatie Medialibrary Example</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
  
<body>
    <div class="container">
        <h1>Create Post</h1>
        <div class="d-flex p-2 bd-highlight mb-3">
            <a href="{{ route('posts.index') }}" class="btn btn-outline-danger btn-sm">Go Back</a>
        </div>
        <div>
            <form action="{{ route('posts.store') }}" enctype="multipart/form-data" method="post">
                @csrf
                <div class="mb-3">
                    <label>Title</label>
                    <input type="text" name="title" class="form-control">
                </div>
                <div class="mb-3">
                    <label>Body</label>
                    <textarea class="form-control" name="body"></textarea>
                </div>
                <div class="mb-3">
                    <label>Image:</label>
                    <input type="file" name="image" class="form-control">
                </div>
                <div class="d-grid">
                    <button class="btn btn-success">Submit</button>
                </div>
            </form>
        </div>
    </div>
</body>
  
</html>

Add App URL in env File

In this step, you have to open the .env configuration file and look for the APP_URL variable and append the given url in-front.

APP_URL = http://localhost:8000

Run Laravel Application

By default, the public disk utilizes the local driver and stores its files in storage/app/public. To make these files accessible from the web, you should create a symbolic link from public/storage to storage/app/public.

So, we can create the symbolic link to access the storage directory using the artisan command publicly.

php artisan storage:link

You have reached final at the end of the tutorial, now start the app using the php artisan command:

php artisan serve

Here is the link which will help you open the app on the browser and test.

http://localhost:8000/posts

Hope this will work for you..

Leave a Comment