Upload in Laravel Inertia

The file upload process is fundamental in any system today, being able to upload images for publications, for an avatar, or documents that are part of a cycle in the application, are routine processes today, therefore, now we will know how to create a file upload process using Laravel Inertia.

Thanks to these skeletons or scaffolding they have an excellent integration with Laravel, we can use practically the same code from the server side, that is, from Laravel, in the client with Vue, we can also use practically the same, but, when using requests with Inertia, here if things change a bit as we will know in detail below.

Web file upload (also known as file upload) is a functionality that allows you to upload or send files from your PC or local computer in general to the web server where the Laravel application is located.

This functionality is crucial in practically any web application that requires uploading files such as images, audio files, text documents, videos, etc. File upload can be implemented in various ways, such as using HTML forms, which has been the most classic, but HTTP requests can also be used, either directly or through plugins that facilitate the implementation of this functionality, such as Dropzone.js or OrugaUI.

File upload from Laravel

As always, let's start by creating a disk in the public folder, so we can access them:

config/filesystems.php

'public_upload' => [
    'driver' => 'local',
    'root' => public_path(),
],

We create the controller destined to perform the upload, as you can see, the process is exactly the same as we would follow in basic Laravel:

app/Http/Controllers/Dashboard/PostController.php

public function upload(Request $request, Post $post)
    {
        $request->validate(
            [
                'image' => 'required|mimes:jpg,jpeg,png,gif|max:10240'
            ]
        );
        Storage::disk("public_upload")->delete("image/post/".$post->image);
        $data['image'] = $filename = time()."." .$request['image']->extension();
        $request->image->move(public_path("image/post"),$filename);
        $post->update($data);
        return to_route('post.index')->with('message', "Upload image to post successfully");
    }

Create validations to indicate the type and weight of the maximum file:

$request->validate( [ 'image' => 'required|mimes:jpg,jpeg,png,gif|max:10240' ] )

Indicate the destination folder, for this we use the previously created disk:

$request->image->move(public_path("image/post"),$filename);

We generate a name for the file:

$data['image'] = $filename = time()."." .$request['image']->extension();

We update the entity, in this case, a post:

$post->update($data);

Uploading files from a component in Vue

For the component in Vue, we will use a button to click with the upload function, you can use any other mechanism either a separate upload process or that is part of a form, as we see in the Laravel Inertia course and book:

<jet-button class="mt-3" @click="upload">Send</jet-button>

We will also use a file type field to load it, the important thing is to note that, to reference the file we use:

@input="form.image = $event.target.files[0]"

This is the fundamental part that you have to take into account when using Inertia instead of any other process, with this, the file is selected in our v-model:

<jet-input class="w-full" type="file" @input="form.image = $event.target.files[0]" />

For the upload function, we use the Inertia post function, it is important to note that, for file upload processes in Inertia, we can only use post type requests:

function upload() {
      Inertia.post(route("post.upload", form.id), form);
}

Finally, the complete code of the component in Vue:

 </jet-form-section>
    <div class="container">
      <div class="card">
        <div class="card-body">
          <div class="grid grid-cols-2 gap-2">
            <div>
              <jet-label value="Image" />
              <jet-input
                class="w-full"
                type="file"
                @input="form.image = $event.target.files[0]"
              />
              <jet-input-error :message="errors.image" />
            </div>
            <div>
              <jet-button class="mt-3" @click="upload">Send</jet-button>
            </div>
          </div>
        </div>
      </div>
    </div>
setup(props) {
    const form = useForm({
      // ***
      image: "",
    });
    function submit() {
      Inertia.put(route("post.update", form.id), form);
    }
    function upload() {
      Inertia.post(route("post.upload", form.id), form);
    }
    return { form, submit, upload };
  },

Finally, we create the route:

routes/web.php

Route::group(['middleware' => [
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified',
]], function () {
    Route::resource('/category', App\Http\Controllers\Dashboard\CategoryController::class);
    Route::resource('/post', App\Http\Controllers\Dashboard\PostController::class);
    Route::post('/post/upload/{post}', [App\Http\Controllers\Dashboard\PostController::class,'upload'])->name('post.upload');
});

If you wanted to use other types of requests, you can do it without problems by indicating the option of always sending a POST type request and indicating with the _method, the method that you really want to use.

- Andrés Cruz

En español
Andrés Cruz

Develop with Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz In Udemy

I agree to receive announcements of interest about this Blog.