Components

File Upload

A drag-and-drop dropzone with image thumbnails, file sizes and per-file progress bars.

php artisan blatui:add file-upload

Drag & drop files here, or click to browse

Up to 10MB

<div class="w-full max-w-md">
    <x-ui.file-upload name="document" maxSizeLabel="Up to 10MB" />
</div>

Existing Files

Drag & drop files here, or click to browse

Up to 10MB

Removed — clear it on the record.

{{-- An edit form: the record already has a file, so the field starts holding it. Removing one
     dispatches file-remove — the component can withdraw an upload it made, never a file that
     was saved before the page rendered. --}}
<div class="w-full max-w-md" x-data="{ removed: null }" x-on:file-remove="removed = $event.detail.name">
    <x-ui.file-upload
        name="attachments"
        multiple
        maxSizeLabel="Up to 10MB"
        :value="[
            '/placeholder.svg',
            ['url' => '/contract.pdf', 'name' => 'contract.pdf', 'size' => 248320],
        ]"
    />
    <p class="text-muted-foreground mt-2 text-xs" x-show="removed" x-cloak>
        Removed <span class="font-medium" x-text="removed"></span> — clear it on the record.
    </p>
</div>

Image Preview

Drag & drop files here, or click to browse

image/* · PNG, JPG or GIF

<div class="w-full max-w-md">
    <x-ui.file-upload name="photos" multiple accept="image/*" maxSizeLabel="PNG, JPG or GIF" />
</div>

Multiple

Drag & drop files here, or click to browse

.pdf,.doc,.docx,.txt · Max 5 files

<div class="w-full max-w-md">
    <x-ui.file-upload name="attachments" multiple accept=".pdf,.doc,.docx,.txt" maxSizeLabel="Max 5 files" />
</div>

With Progress

Drag & drop files here, or click to browse

Progress tracks the real upload

{{-- The bar is Livewire's own upload progress, so it appears when there is an upload behind
     the field. In a plain form the component lists what you picked and draws no bar — nothing
     is being uploaded yet. --}}
<div class="w-full max-w-md">
    <x-ui.file-upload wire:model="uploads" multiple maxSizeLabel="Progress tracks the real upload" />
</div>

Using with Livewire

wire:model

The examples above are the frontend (Blade + Alpine) usage. Inside a Livewire component, bind wire:model for two-way state — same component, no wrappers. Full Livewire guide →

app/Livewire/Demo.php
use Livewire\Component;

class Demo extends Component
{
    public $avatar;

    public function render()
    {
        return view('livewire.demo');
    }
}
resources/views/livewire/demo.blade.php
<x-ui.file-upload wire:model="avatar" accept="image/*" />

Add the Livewire\WithFileUploads trait to the component for temporary uploads.

API Reference

Props, slots and exposed methods for <x-ui.file-upload>.

Props

Prop Type Default Description
name string The name attribute of the hidden file input, so selected files submit with a form. With multiple, "[]" is appended.
multiple bool false Allow selecting more than one file.
accept string The native accept filter (e.g. "image/*,.pdf"). Also shown in the dropzone hint line.
wire:model string Bind to a Livewire property (with the WithFileUploads trait). Livewire uploads the selection — picked or dropped — and the per-file bar reports its real progress, turning into an error message if the upload fails. Without it nothing is uploading, so no bar is drawn and the files ride along with the surrounding form.
maxSizeLabel string A human-readable size hint (e.g. "Up to 10MB") shown in the dropzone. Display only — not enforced.
value string|array The file(s) the field already holds — what an edit form has saved against the record. A URL, a list of URLs, or maps with url/name/size/image. Each becomes an ordinary row with the same thumbnail and the same remove button, so the preview does not have to be rebuilt outside the component. Removing one dispatches file-remove; the component cannot delete a file it did not upload.
disabled bool false Disable the dropzone and the underlying input so no files can be added.
id string Id for the hidden file input. None is generated when omitted — a per-render id would be a per-render morph key, and Livewire would replace the input mid-upload.

Events

Events the component listens for (in) and dispatches (out). Both directions bubble, so .window works even when the component is teleported.

Event Direction Detail
file-remove Out { url, name } A row that came from value was removed. The file is already saved and is not the component's to delete, so this is how it says so — listen for it to clear the column on your record.

Methods

Available on the component's Alpine scope — call them from markup in the slot (e.g. @click="…").

Method Description
open() Open the native file picker (the same action as clicking the dropzone).
remove(index) Remove the file at the given index: drops the row, revokes its preview URL, withdraws the temporary Livewire upload (or takes the file back off the native input when there is no wire:model). A row that came from value is only announced — see file-remove.