Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Filament Media Manager Laravel Package

juniyasyos/filament-media-manager

A Filament media manager for browsing, uploading, and organizing files and folders through an intuitive interface. Manage images and media assets directly from your admin panel with a clean, responsive UI built for Laravel and Filament applications.

View on GitHub
Deep Wiki
Context7

Getting Started

This package is a Filament panel plugin that puts a folder-based media browser (backed by spatie/laravel-medialibrary) into your admin UI, plus a form component for picking existing media when editing records.

Minimal install:

composer require juniyasyos/filament-media-manager
php artisan vendor:publish --tag="filament-media-manager-config"
php artisan vendor:publish --tag="filament-media-manager-migrations"
php artisan migrate
php artisan storage:link

Register it on the panel you want it in (app/Providers/Filament/AdminPanelProvider.php):

->plugin(FilamentMediaManagerPlugin::make())

Look at these first, in this order:

  1. config/filament-media-manager.php — disk, accepted file types, base path, and the media model binding. Almost every "it doesn't work" report traces back here.
  2. The plugin class itself — it is small; it registers the page, navigation group, and assets. Read it before overriding anything.
  3. The published migration / Media model — confirm whether the package ships its own model or defers to Spatie's, because that determines where you add conversions.

First use case: open the Media Manager page in the panel, create a folder, upload an image, then drop the package's media-picker field into an existing Resource form whose model uses Spatie's InteractsWithMedia. That end-to-end loop (upload → pick → render getFirstMediaUrl()) exercises disk config, the storage symlink, and the picker's state handling all at once — do it before wiring anything into production forms.

Prerequisites worth checking up front: Filament v3 (v4 is not guaranteed), PHP 8.1+, and a User model that implements FilamentUser if your panel is non-local — otherwise the page registers but nobody can reach it.

Implementation Patterns

Attach selected media to a model. The picker gives you a media ID or path, not a file. The clean pattern is to keep the field as a non-persisted form input and move the media in a lifecycle hook, so you are not fighting Spatie's own media relationship:

MediaPicker::make('featured_media_id')
    ->label('Featured image')
    ->dehydrated(false)
    ->afterStateHydrated(fn ($component, $record) => $component->state(
        $record?->getFirstMedia('featured')?->id
    ));

Then, in afterCreate / afterSave on the page (or a mutateFormDataBeforeSave that strips the key), copy the media onto the record's collection.

Collections over ad-hoc paths. Decide your collection names (featured, gallery, documents) and register conversions on the model, not in the package. The manager becomes the shared library; the model owns the rendering contract. This keeps you free to replace the UI later.

Multi-tenant / per-user folders. The directory shown is derived from the filesystem path, so tenancy is handled by scoping that path — either via the config base path or by overriding the page's directory resolution for the current tenant. Register the plugin per panel; for a tenant panel, give each tenant a subdirectory and reuse one Spatie Media model.

S3 or other non-local disks. Set the disk in config and verify the browser component can list it. Local disk is the well-trodden path; object storage works but you lose the cheap storage:link shortcut and need signed/temporary URLs configured on the Filament filesystem driver.

Gate it like any other page. Because it is a full page with delete and upload powers, wire it into your policy layer. Simplest version: FilamentMediaManagerPlugin::make()->navigationGroup('Content') plus a canView() check, or ->shouldRegisterNavigation(false) and link to it only from authorised contexts.

Compose with Relation Managers. For galleries and attachments, a relation manager or repeater whose field is the media picker scales better than one giant "attachments" collection, and it keeps the media table from becoming a single hot relationship.

Gotchas and Tips

  • The v1.4.1 release notes contain no description — just a compare link, and the base tag in that link (3.0) does not follow the same scheme as v1.4.1. Read the actual diff on GitHub before upgrading, and pin the exact version in composer.json rather than using a floating constraint until the tag scheme is clarified.
  • Broken thumbnails are almost always storage:link or disk mismatch, not the package. Confirm the file exists under storage/app/public/..., that APP_URL is correct, and that the config disk matches the disk the model was saved with.
  • Config caching bites on disk changes. After editing accepted_file_types or disk, run php artisan config:clear (and filament:optimize-clear if you optimise).
  • Upload limits are three layers deep: PHP upload_max_filesize / post_max_size, Livewire's temporary upload rules, and Filament's own maxSize(). A silent failure on large files usually means the middle layer.
  • Folders are real directories. Renaming or moving files outside the UI desynchronises the tree from the database; treat the filesystem as package-owned.
  • Deletion is destructive and immediate. The UI removes the file and the row. If you need recovery or audit, soft-delete the media model and add a pruning job instead of relying on the UI's delete.
  • Extend the media model via config, not by editing vendor files — point the package at your own subclass and put registerMediaConversions() and custom accessors there, then php artisan vendor:publish --force safely on upgrades.
  • Asset republishing after upgrades: run php artisan filament:assets so the page's JS matches the installed PHP version; a stale asset manifest produces an empty or inert file browser.
  • Navigation appears for every panel user by default. If your panel has non-admin roles, gate the page before you ship, or you have effectively given every logged-in user file deletion rights.
  • It is a thin skin over Spatie. When something is genuinely wrong, reproduce it with $model->addMedia(...) outside Filament first — that tells you within a minute whether you are debugging the package or the media library.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console