Laravel 9 Images Upload with Spatie Media Library Tutorial

Laravel Spatie medialibrary tutorial. This detailed guide will help you discover how to create image upload in the Laravel application using the Spatie media library package.

Nowadays, web developers have innumerable PHP app development frameworks options; however, Laravel stands apart for rapid and reliable PHP development.

There are plenty of reasons to choose laravel for your next web application project. It offers individual components which are developed or managed by someone else; It is primarily known by packages. A package is a small piece of code that is responsible for managing a particular functionality or feature.

In this Laravel Spatie example, we will explain how to add the spatie media library in the laravel application for uploading avatars or images. Also, we will create a basic form, store the form values and the images on the database and display the data list on the application’s view.

How to Implement Spatie Media Library in Laravel 9 App

  • Step 1: Create New Laravel Project
  • Step 2: Database Connection
  • Step 3: Define App Url
  • Step 4: Add Spatie Medialibrary Package
  • Step 5: Create Model and Migration
  • Step 6: Formulate New Controller
  • Step 7: Register Routes
  • Step 8: Create Blade View Template
  • Step 9: Evoke Development Server

Create New Laravel Project

We need a new project to build the desired functionality. If you have installed Composer globally, run the command for installing the Laravel app.

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

Database Connection

Laravel is not a common framework, and it offers the best tools for interacting with databases.

Let us configure the database by adding the database credentials in .env for making the flawless connection.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=db_name
DB_USERNAME=db_username
DB_PASSWORD=db_password

Define App Url

In this step we have to add the localhost url to the APP_URL variable in the .env.

...
...
APP_URL = http://localhost:8000
...
...

Add Spatie Medialibrary Package

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

composer require "spatie/laravel-medialibrary:^9.6.0"

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

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

Create Model and Migration

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

php artisan make:model Blog -m

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

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

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;


class CreateBlogsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('blogs', function (Blueprint $table) {
            $table->id();
            $table->string('title');            
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('blogs');
    }
}

Open app/Models/Blog.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\HasMedia;
use Spatie\MediaLibrary\InteractsWithMedia;


class Blog extends Model implements HasMedia
{
    use HasFactory, InteractsWithMedia;

    protected $fillable = [
        'title',
    ];    
}

Once you updated the migrations file and use the artisan migration command.

php artisan migrate

Formulate New Controller

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

php artisan make:controller BlogController

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

<?php

namespace App\Http\Controllers;

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


class BlogController extends Controller
{
    public function index()
    {    
        $blogs = Blog::latest()->get();
        return view('index', compact('blogs'));
    }

    public function mediaView()
    {
        return view('media');
    }
    
    public function store(Request $request)
    {
        $input = $request->all();
        $blog = Blog::create($input);
        if($request->hasFile('img') && $request->file('img')->isValid()) {
            $blog->addMediaFromRequest('img')->toMediaCollection('img');
        }
        return redirect()->route('blog');
    }
}

Register 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\BlogController;


/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('blog',[
    BlogController::class,'index'
])->name('blog');

Route::get('blog/create',[
    BlogController::class,'mediaView'
])->name('blog.create');

Route::post('blog/store',[
    BlogController::class,'store'
])->name('blog.store');

Create Blade View Template

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/index.blade.php file.

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8">
    <title>Implement Spatie Media Library in Laravel</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container">
        <div class="d-flex p-2 bd-highlight">
            <a href="{{ route('blog.create') }}" class="btn btn-primary">Create Blog</a>
        </div>
        <table class="table mt-4">
            <thead>
                <tr>
                    <th>#</th>
                    <th>Title</th>
                    <th>Profile Pic</th>
                </tr>
            </thead>
            <tbody>
                @foreach($blogs as $key=>$data)
                <tr>
                    <td>{{ ++$key }}</td>
                    <td>{{ $data->title }}</td>
                    <td><img src="{{$data->getFirstMediaUrl('img', 'thumb')}}" / width="130px"></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>

<head>
    <meta charset="utf-8">
    <title>Laravel Demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>

<body>
    <div class="container">
        <div class="d-flex p-2 bd-highlight mb-2">
            <a href="{{ route('blog') }}" class="btn btn-primary">Go Back</a>
        </div>
        <div>
            <form action="{{ route('blog.store') }}" enctype="multipart/form-data" method="post">
                @csrf
                <div class="mb-2">
                    <label>Title</label>
                    <input type="text" name="title" class="form-control">
                </div>
                <div class="mb-2">
                    <label>Profile Image</label>
                    <input type="file" name="img" class="form-control">
                </div>
                <div class="d-grid">
                    <button class="btn btn-danger">Save</button>
                </div>
            </form>
        </div>
    </div>
</body>

</html>

Evoke Development Server

In the final segment, we have to create the symbolic link, execute the given below command.

php artisan storage:link

You have set up the application, just run the following command and start the application on the given link.

php artisan serve
http://localhost:8000/blog

Laravel Images Upload with Spatie Media Library Tutorial

Summary

In this tutorial, you have learned the basic know-how of the Spatie media library, how to add a spaite media library in laravel to upload photos with the basic form. Moreover, we had a look at the laravel file system, and we aimed to make developers happy.

It is now upto you to look more deeply into the confluence of laravel and spatie and find the answer to the learning curve to minimize the difficulties.