v1 LiVue v1 is here — server-driven reactivity for Laravel using Vue.js Get Started →
Back to articles

LiVue Articles

File Uploads in LiVue with Loading States (Required Steps)

Published March 10, 2026

File upload is one of those features that feels simple to users only when feedback is clear.

In LiVue, the required flow is short: declare upload support, bind the input, validate/store on submit, and show loading state while work is in progress.

This guide stays focused on required steps only.

Required flow (high-level)

  1. Enable uploads in the component.
  2. Bind the file input with livue.upload(...).
  3. Show upload/loading feedback in the template.
  4. Validate and store the file on submit.

1) Enable uploads in the component

<?php

namespace App\LiVue;

use LiVue\Component;
use LiVue\Features\SupportFileUploads\TemporaryUploadedFile;
use LiVue\Features\SupportFileUploads\WithFileUploads;

class AvatarUpload extends Component
{
    use WithFileUploads;

    public ?TemporaryUploadedFile $avatar = null;

    public function save(): void
    {
        if ($this->avatar === null) {
            return;
        }

        $this->validate([
            'avatar' => ['required', 'image', 'max:2048'],
        ]);

        $this->avatar->store('avatars');
        $this->avatar = null;
    }

    protected function render(): string
    {
        return 'livue.avatar-upload';
    }
}

2) Bind the upload input in Blade

<div class="space-y-3">
    <input
        type="file"
        accept="image/*"
        @change="livue.upload('avatar', $event.target.files[0])"
    >

    <button @click="save()" :disabled="livue.loading">
        Save avatar
    </button>
</div>

3) Add loading and progress feedback

<div v-if="livue.uploading" class="text-sm">
    Uploading: @{{ livue.uploadProgress }}%
</div>

<div v-if="livue.isLoading('save')" class="text-sm">
    Saving file...
</div>

There are two useful signals here:

  • livue.uploading / livue.uploadProgress for transport progress
  • livue.isLoading('save') for server action status

This combination makes the UI feel responsive and predictable.

4) Handle errors in the same template

<span v-if="$errors.avatar" class="text-red-500 text-sm">
    @{{ $errors.avatar }}
</span>

Why this pattern is enough for most apps

  • Small surface area to maintain.
  • Clear user feedback during both upload and save.
  • Validation and persistence remain server-side.

Start from this baseline, then add extras (multiple files, previews, custom disks) only when your use case needs them.

Documentation links