Components
File Upload
A drag-and-drop dropzone with image thumbnails, file sizes and per-file progress bars.
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 →
use Livewire\Component;
class Demo extends Component
{
public $avatar;
public function render()
{
return view('livewire.demo');
}
}
<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. |