cleaniquecoders/media-manager
A Laravel media management package for uploading, organizing, and attaching files to Eloquent models. It provides a simple API for images and documents, storage disk integration, and reusable media associations so you can manage assets without writing upload logic yourself.
Install and publish
composer require cleaniquecoders/media-manager
php artisan vendor:publish --tag=media-manager-views
The package ships Livewire components (the media collection UI lives in livewire/media-collection.blade.php), so confirm Livewire is installed and your layout includes its assets before rendering anything.
Where to look first
media-collection — read its public properties and actions before writing your own wrapper.First use case
Attach media to a model, render the collection component, and let editors drag to reorder:
<livewire:media-collection :model="$post" collection="gallery" />
Confirm three things work end to end: upload, delete, and drag-to-reorder persisting after a page refresh. The ordering behaviour is exactly what changed in 1.2.2, so it's the first thing to validate on any new install.
Upgrading to 1.2.2
composer update cleaniquecoders/media-manager
php artisan vendor:publish --tag=media-manager-views --force
php artisan view:clear
Then re-test sorting. If you skip the re-publish, you keep the old view and the fix never reaches your app.
Version-pin the published views. Because the sorting implementation lives in a Blade file you own after publishing, composer update alone does not upgrade the UI. Treat "bump the package" and "diff the published views" as two steps in the same PR. A quick habit: after any package update, run php artisan vendor:publish --tag=media-manager-views without --force and check what the package tried to write, or diff resources/views/vendor/... against vendor/cleaniquecoders/media-manager/resources/views/.
Keep overrides thin. If you need custom markup, copy the published view and change only what you must — the less you diverge, the cheaper each future re-publish is. Note the reason for the override in a comment so the next developer knows whether it's still needed.
Read order from your own code, not the DOM. Persist a sort column (or use the package's ordering) and expose an ordered relationship/scope so front-end rendering doesn't depend on whatever order the media table happens to return. That way a broken drag interaction degrades to "wrong order" instead of "random order."
Pair with a strict CSP deliberately. With 1.2.2 the sorting UI no longer pulls SortableJS from cdn.jsdelivr.net, so a script-src 'self' policy works out of the box. If you run a strict CSP, this is the release that lets you stop maintaining an exception for the CDN host. Grep your published views for jsdelivr to be sure nothing stale remains (see Gotchas).
Test the interaction in Livewire tests. Use Livewire::test() against the component, call the reorder action with a new ID sequence, and assert the persisted order — this catches regressions if you later customize the view.
Front-end build hygiene. Since the interaction is now native browser behaviour, there's no JS dependency to bundle or version. Don't add your own drag library on top unless you actually need touch support; two competing handlers on the same list produce dropped events and duplicated writes.
The #1 pitfall: stale published views. composer require/update will not touch your published Blade files. After 1.2.2, an un-re-published livewire/media-collection.blade.php still references the CDN script, so a CSP-blocked production environment keeps failing while composer.lock shows 1.2.2. Confirm by inspecting the rendered page source for cdn.jsdelivr.net — if it's there, re-publish.
Be careful with --force. It overwrites your customizations with no diff and no undo. Commit first, then re-publish, then git diff to re-apply your intentional changes.
Native HTML5 drag-and-drop has no touch support. This is the trade-off of dropping SortableJS: desktop mouse dragging works, but drag on iOS/Android typically won't fire dragstart. If editors work on tablets, either test on-device before shipping or provide an explicit "move up / move down" fallback action. Don't discover this in production.
CSP tightening checklist. After re-publishing, remove cdn.jsdelivr.net from script-src (and from any preload/connect-src entries if present), then load the page with the browser console open and confirm zero CSP violation reports. Watch for other CDN references — fonts, icons — that you may have been tolerating for the same reason.
Debugging order problems. Work down this list: (1) does the request fire on drop — check the network tab for the Livewire update request; (2) does it carry the new sequence; (3) does the server persist it — check the sort/order column in the DB; (4) does the rendered list re-read that column. A failure at step 1 with a clean network tab usually means stale published views or a CSP block; failures at 3 usually mean a route/permission or mass-assignment issue.
Cache clearing is still your friend. php artisan view:clear after re-publishing avoids the confusing case where a compiled Blade file keeps serving the old CDN reference even though the source view is correct.
Extension points to prefer. Custom properties/actions on the Livewire component and config-level settings are cheaper to maintain than forked views. Reach for a view override only when the markup itself must change.
How can I help you explore Laravel packages today?