Download the PHP package codebyray/livewire-media-uploader without Composer
On this page you can find all versions of the php package codebyray/livewire-media-uploader. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Download codebyray/livewire-media-uploader
More information about codebyray/livewire-media-uploader
Files in codebyray/livewire-media-uploader
Package livewire-media-uploader
Short Description Reusable Livewire v3/v4 media uploader that integrates with Spatie Media Library and ships a publishable view.
License MIT
Informations about the package livewire-media-uploader
Livewire Media Uploader
Livewire Media Uploader is a reusable Livewire v3/v4 component that integrates seamlessly with Spatie Laravel Media Library. It ships a clean Tailwind Blade view by default (fully publishable), Bootstrap theme as an option, Alpine overlays for previews/confirmations, drag-and-drop uploads, per-file metadata (caption/description/order), configurable presets, name-conflict strategies, and optional SHA-256 duplicate detection. Drop it in, point it at a model, and you’re shipping in minutes.
Table of Contents
- Features
- Requirements
- Installation
- Publishing Assets
- Theme System
- Dark Mode - Tailwind
- Custom Theme
- Quick Start
- Usage Examples
- Create flow (deferred uploads)
- Configuration
- Props
- Events
- Authorization
- Model Setup (Spatie Media Library)
- Overlays & UX Notes
- Troubleshooting
- Roadmap
- License
Features
- ✅ Livewire v3/v4 component with themeable Blade UI
- Tailwind (default)
- Bootstrap (optional)
- Fully publishable and overridable
- ✅ Spatie Media Library integration (attach, list, edit meta, delete)
- ✅ Publishable view for per-project customization
- ✅ Drag & drop uploads + progress bar
- ✅ Inline edit of caption / description / order
- ✅ Name-conflict strategies: rename | replace | skip | allow
- ✅ Optional exact duplicate detection via SHA-256
- ✅ Collection → preset mapping (auto
acceptattribute) - ✅ Image preview overlay + delete confirmation modal
- ✅ Optional authorization hook (
authorizeAbility) — delegates to your app's own Gate/Policy, no auth package required - ✅ Works with:
- Saved model instance (
:for="$model") - String model + id (
model="user" :id="1") - FQCN, morph map alias, or dotted paths with custom namespaces
- Local alias map
- Saved model instance (
Requirements
- PHP 8.2+
- Laravel ^12.0 | ^13.0
- Livewire ^3.0 | ^4.0
- spatie/laravel-medialibrary ^10.12 | ^11.0
- TailwindCSS (optional but recommended for the default view)
- Alpine.js (used by overlays/progress; see Overlays & UX Notes)
- CSS depending on theme:
- Tailwind theme → TailwindCSS (recommended)
- Bootstrap theme → Bootstrap CSS (no Bootstrap JS required; Alpine drives modals)
Note on Laravel 10/11: Earlier releases of this package listed Laravel 10 and 11 as supported. Both are now past their security-support window (Laravel 10 is EOL; Laravel 11 security support ended March 2026), and current releases of
laravel/frameworkin those lines carry known, unpatched advisories — meaning a freshcomposer installtargeting either will be blocked by Composer's own audit for most consumers. Support for both has been dropped as ofv0.5.0. If you're still running Laravel 10/11, pin this package tov0.4.x, but prioritize upgrading Laravel first — that's the more urgent fix.Every PHP/Laravel/Livewire combination listed above is verified on every push via GitHub Actions.
Installation
Auto-discovery will register the service provider. If you disable discovery, add:
The component is registered under both aliases:
<livewire:media-uploader ... /><livewire:media.media-uploader ... />
Publishing Assets
Config:
Views:
After publishing, customize the Blade at:
Theme System (Tailwind + Bootstrap + custom)
Select the theme in config/media-uploader.php:
Dark mode (Tailwind theme)
This package’s Tailwind theme is dark-ready. Add this tiny snippet in your main layout <head> to apply the user’s saved choice / system default:
Custom themes
- Copy an existing theme directory (e.g. themes/tailwind) to themes/custom and edit the Blade.
-
Register it in the map and select it:
Note: The component’s Livewire + Alpine behavior is identical across themes. Only classes/markup differ. If you use the Bootstrap theme, make sure your layout includes Bootstrap CSS.
Environment variables (optional)
You can override preset limits and accepted types/mimes via .env. These map directly to config/media-uploader.php:
Notes
- Values are comma-separated; spaces are OK (the package trims them).
-
After changing .env, run:
- The `` attribute is auto-filled from the active preset when accept_from_config is true (default). You can still override it per-component with the accept prop.
- If uploads fail due to size, make sure your PHP/Server limits also allow it (e.g. upload_max_filesize, post_max_size).
Quick Start
1) Ensure your target Eloquent model implements Spatie\MediaLibrary\HasMedia and is saved.
Model Setup (Spatie Media Library)
Your model must implement HasMedia and be saved before attaching media.
2) Include Livewire & Alpine (usually in your app layout):
3) Drop the component into your Blade:
Usage Examples
1) Pass a saved model instance
2) Short string model + id
3) Morph map alias**
4) FQCN
5) Dotted path + custom namespaces
6) Local aliases (per-instance)
7) Single-file mode + hide list
8) Name conflict strategies
9) Duplicate detection by SHA-256
10) Restrict types/mimes/max size manually
Create flow (deferred uploads)
You can let users pick files before the model exists, and attach them after save.
Blade (create page)
Livewire component (simplified)
How it works
- On create screens, the component accepts model="post" without an id.
- Files and per-file metadata are queued locally.
-
After you persist the model, dispatch:
-
The uploader resolves the saved target, attaches any queued files, and emits media-attached.
Configuration
The package merges config/media-uploader.php:
accept_from_config— iftrue, auto-fills<input accept>from the selected presetcollections— map collection name → preset keypresets.*.types— extensions (comma-separated)presets.*.mimes— MIME types (comma-separated)presets.*.max_kb— max file size per file in KB
Example:
Show all collections together (grouped)
Set :list-all="true" to render a grouped list of every collection on the target model. Items stay fully editable.
The component decides the active preset in this order:
- Explicit
$presetprop - Mapping from
collections - Fallback to
default
Props
| Prop | Type | Default | Description |
|---|---|---|---|
for |
Model |
— | Saved Eloquent model instance implementing HasMedia. |
model |
string |
— | Model resolver: alias, FQCN, morph alias, or dotted path. |
id |
int|string |
— | Target model id (used with model). |
collection |
string |
images |
Media collection name. |
disk |
?string |
null |
Storage disk (e.g. s3). |
multiple |
bool |
true |
Toggle multi-file input. |
accept |
?string |
null |
<input accept> override (otherwise may be auto from config). |
showList |
bool |
true |
Show the attached media list. |
maxSizeKb |
int |
500 (overridden to preset’s max_kb if empty) |
Max file size (KB). |
preset |
?string |
null |
Choose a preset (images, docs, videos, default, etc.). |
allowedTypes |
array |
[] |
Extensions filter (e.g. ['jpg','png']). |
allowedMimes |
array |
[] |
MIME filter (e.g. ['image/jpeg']). |
onNameConflict |
string |
rename |
Strategy: rename | replace | skip | allow. |
skipExactDuplicates |
bool |
false |
Uses SHA-256 stored in custom_properties->sha256. |
namespaces |
array |
['App\\Models'] |
Namespaces for dotted-path resolution. |
aliases |
array |
[] |
Local alias map, e.g. ['profile' => \App\Models\User::class]. |
attachedFilesTitle |
string |
"Current gallery" |
Heading text in the list card. |
listAll |
bool |
false |
When true, the attached media list shows all collections, grouped by collection name (still editable). |
authorizeAbility |
?string |
null |
Gate/Policy ability checked against the target model before upload/delete/edit/attach. See Authorization. |
Events
The component dispatches browser events you can listen for:
media:attach— incoming event the component listens for. Arguments:model(class/alias),id, optionalcollection, optionaldisk. Triggers attaching of any queued files to the now-saved target.media-attached— emitted after a successfulmedia:attach. Payload:{ model: FQCN, id: string }.media-uploaded— emitted after an immediate upload (when a target already exists).media-deleted— emitted after deletion (detail.idcontains the Media ID).media-meta-updated— emitted after inline metadata is saved.
Example:
Authorization
By default, the component does not perform any authorization. It verifies that a given Media record belongs to the resolved target model before allowing edits/deletes, but it does not check whether the current user is allowed to modify that model. It's your app's responsibility to ensure the component only renders where the user already has access (route middleware, a policy check before rendering the page, etc.).
If you'd like the component to enforce this itself, set authorizeAbility to a Gate/Policy ability name. It's checked against the resolved target model before every mutating action (uploadFiles, remove, saveEdit, and the media:attach event handler), using Laravel's own Gate::authorize() — no extra package required, and it plays nicely with anything already wired up (Policies, Gate closures, Spatie Permissions via a Gate, etc.).
With the example above, before any upload/delete/edit/attach action runs, the component calls the equivalent of Gate::authorize('update', $post). If your PostPolicy::update() returns false, the action aborts with a 403 instead of proceeding.
Notes:
- One ability is checked for all mutating actions. If you need
deleteandupdateto map to different Policy methods, don't setauthorizeAbility— instead wrap the component's Blade usage behind your own check, or open an issue/PR describing the use case. - The
channelprop used with themedia:attachevent is a namespacing convenience for routing the event to the right component instance — it is not an authorization boundary. UseauthorizeAbility(or your own upstream checks) if untrusted input could influence whichmodel/idgets dispatched tomedia:attach. - Leaving
authorizeAbilityunset preserves the exact behavior of versions prior to0.5.0— this is a fully backward-compatible, opt-in addition.
The list view tries
getUrl('thumb')and falls back togetUrl()if no conversion is available.
Overlays & UX Notes
- Image Preview Overlay (lightbox): toggled by
x-show="preview.open". - Delete Confirmation Modal: toggled by
$wire.confirmingDeleteId !== null. -
Add once in your layout to prevent flash-of-overlay:
- Z-index defaults: preview
z-[60], delete modalz-50. Adjust to your stack if you have higher layers.
Troubleshooting
-
“Target model must be saved…”
Ensure the model exists in DB ($model->exists === true) before rendering the component. -
“must implement Spatie\MediaLibrary\HasMedia”
Addimplements HasMedia+InteractsWithMediato your model. -
Unknown model class/alias
If usingmodel="something"+:id, make sure:- It’s a valid FQCN, morph alias, or maps via dotted path within
namespaces, or - You passed a local alias via
:aliases="['something' => \App\Models\YourModel::class].
- It’s a valid FQCN, morph alias, or maps via dotted path within
-
acceptnot applied
Setaccept_from_config=trueand ensure your preset hastypes/mimes. Or override viaacceptprop. - No thumbnails
Add athumbconversion (see Model Setup).
Roadmap
- Drag-to-reorder (update
order_column). - Show document icon instead of thumbnail in Attached media list if the file is not an image.
PRs welcome!
License
MIT © CodebyRay (Ray Cuzzart II)
Component aliases: media-uploader and media.media-uploader
View namespace: media-uploader::livewire.media-uploader
All versions of livewire-media-uploader with dependencies
livewire/livewire Version ^3.0 || ^4.0
laravel/framework Version ^12.0 || ^13.0
spatie/laravel-medialibrary Version ^10.12 || ^11.0