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 Laravel Package

waad/filament-media

A Filament media manager for browsing, uploading, and organizing images and files in your admin panel. Includes reusable media library UI and fields for attaching media to Eloquent models, simplifying file selection and management across Filament resources.

View on GitHub
Deep Wiki
Context7

Getting Started

waadmawlood/filament-media is a Filament plugin that adds a media library (upload, browse, pick, and attach files) to a panel. The day-to-day value is that you stop hand-rolling upload fields and a media table for every project.

Minimal path to first value:

  1. composer require waadmawlood/filament-media
  2. Publish and run what the package ships (config, migrations, assets) — typically:
    php artisan vendor:publish --tag="filament-media-config"
    php artisan vendor:publish --tag="filament-media-migrations"
    php artisan migrate
    php artisan storage:link
    
  3. Register the plugin on the panel you want it in:
    public function panel(Panel $panel): Panel
    {
        return $panel
            ->plugins([
                \Waadmawlood\FilamentMedia\FilamentMediaPlugin::make(),
            ]);
    }
    
  4. Create a user, log in, and open the media resource in the navigation — upload one image, then add a media picker field to any existing resource form and select that same image.

Where to look first: the package README for the exact namespace/config key names (they vary between versions), then the published config/filament-media.php. That file is the fastest map of what is configurable — disk, directory, accepted mime types, image conversions, and whether the media resource appears in navigation.

Implementation Patterns

Panel plugin vs. per-resource usage. Registering the plugin gives you the browse/manage UI and navigation entry; the field component is what you actually use inside your own resources. Most projects want both, but you can register the field without exposing the full resource by disabling its navigation in config — useful for client-facing panels where editors shouldn't see a raw media library.

Single vs. multiple attachments. Use the picker field for a single relation (e.g. a cover_image_id) and the multi-select/multiple mode for galleries. Store the foreign key or pivot rows yourself via a normal Eloquent relationship — the package handles selection and upload, not your domain schema. Keeping your own relationship means policies, cascades, and API serialization stay under your control.

Tables and infolists. Point an ImageColumn at the media URL accessor rather than duplicating path logic. For lists with many rows, prefer a thumbnail conversion over the original file so you aren't shipping 4MB JPEGs into an admin table.

Disk and directory strategy. Set the disk in config, not in each field. A common split: public locally, S3 in production, with the directory namespaced (media/{tenant_id}) when you have multi-tenancy. Do this through a config override in a service provider so it can read from the current tenant.

Uploads from the front end. Use the package's upload entry point behind your own controller/FormRequest when uploads come from outside the panel, then run the same Storage::fake() tests you'd write for a hand-rolled upload. Reuse the package's validation rules for mime/size rather than re-declaring them.

Seeding and tests. Storage::fake('public') plus UploadedFile::fake()->image(...) and programmatic creation of media records keeps feature tests deterministic. Don't assert on generated file names; assert on the record and the disk path prefix.

Upgrade hygiene. Pin the version in composer.json and read the changelog between minors — this package is pre-2.0 and refactors the service provider internals as it matures.

Gotchas and Tips

  • v1.1.2 behavior change: the service provider no longer registers views itself. If you previously relied on published view overrides landing in resources/views/vendor/..., verify after upgrading that your overrides still resolve; if not, re-publish or point the field/resource at your own view explicitly. This is a low-risk internal refactor with no reported breaking API changes, but it is the kind of change that silently reverts a custom UI.
  • storage:link is not optional. A perfectly working upload with a broken image is almost always a missing symlink or a disk whose url config doesn't match APP_URL.
  • Cache after config edits. php artisan config:clear and php artisan filament:optimize-clear (or a full optimize:clear) before you start debugging why your new disk setting "isn't applied" — Filament caches components and the panel config aggressively in production.
  • Temporary/livewire uploads land somewhere else first. If uploads succeed but the final file is missing, check the temporary upload disk and livewire.temporary_file_upload rules — the panel's max upload size and PHP's upload_max_filesize/post_max_size are separate limits, and hitting either produces a vague validation error.
  • Authorization is yours. Add a policy for the media model/resource; the plugin registers the resource but won't guess your tenancy rules. Without one, any panel user who can reach the resource can typically delete shared assets.
  • Filename collisions and re-uploads. Decide early whether the same file uploaded twice should dedupe or create two records; the default behavior may not match what your editors expect, and retrofitting dedupe later means a data migration.
  • Navigation and permissions. Hide the media resource in config for panels where it's noise, and gate it with canAccess()/shouldRegisterNavigation() rather than removing the plugin — removing the plugin also removes the field component.
  • Extension points worth knowing: the plugin's config file (disk, directory, accepted types, conversions), the field component's fluent setters (directory, accepted types, multiple), and your own policy/resource overrides. Prefer these over forking the package or editing published views.
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.
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
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource