van-ons/filament-attachment-library
Filament Attachment Library adds a simple attachments manager to your Filament panel: upload files, browse and select existing attachments, and store them in a central library. Includes installer command, migrations/assets, and Tailwind-ready templates.
Install the package:
composer require van-ons/filament-attachment-library:^2.0
php artisan filament-attachment-library:install
Set up a custom Filament theme (required for Tailwind styling):
php artisan make:filament-theme [PANEL_NAME]
Add this to resources/css/filament/[PANEL_NAME]/theme.css:
@source '../../../../vendor/van-ons/filament-attachment-library/resources/**/*.blade.php'
Register the plugin in your PanelProvider:
use VanOns\FilamentAttachmentLibrary\FilamentAttachmentLibrary;
public function panel(Panel $panel): Panel {
return $panel
->plugin(FilamentAttachmentLibrary::make()->navigationGroup('Files'));
}
Use the AttachmentField in a Filament resource:
use VanOns\FilamentAttachmentLibrary\Forms\Components\AttachmentField;
public static function form(Form $form): Form {
return $form->schema([
AttachmentField::make('featured_image'), // Stores in a column
AttachmentField::make('gallery')->relationship(), // Uses `HasAttachments` trait
]);
}
Display attachments in Blade:
<x-laravel-attachment-library-image :src="$attachment" />
HasAttachments trait to your Product model:
use VanOns\LaravelAttachmentLibrary\Concerns\HasAttachments;
class Product extends Model {
use HasAttachments;
}
AttachmentField to your Filament resource form:
AttachmentField::make('gallery')->relationship()->collection('product_gallery')
@foreach($product->gallery as $image)
<x-laravel-attachment-library-image :src="$image" />
@endforeach
AttachmentField::make('column_name') for direct storage in a model column (e.g., featured_image).AttachmentField::make('logo')
->image()
->required()
->maxFiles(1);
AttachmentField::make('field_name')->relationship() for dynamic collections (e.g., galleries, documents).HasAttachments trait on the model.AttachmentField::make('documents')
->relationship()
->collection('contracts')
->mime('application/pdf');
FilamentAttachmentLibrary::make()
->basePath(fn () => 'tenants/' . Filament::getTenant()?->slug)
AttachmentField::make('avatar')->mime('image/jpeg,image/png');
AttachmentField::make('video')->video();
AttachmentField::make('document')->text();
AttachmentField::make('gallery')->multiple()->minFiles(1)->maxFiles(10);
public function gallery(): MorphToMany {
return $this->attachmentCollection('gallery');
}
Product::with('gallery')->get();
AttachmentColumn:
use VanOns\FilamentAttachmentLibrary\Tables\Columns\AttachmentColumn;
Tables\Columns\AttachmentColumn::make('featured_image')
->image()
->width(50)
->height(50);
use VanOns\FilamentAttachmentLibrary\Widgets\AttachmentStats;
public static function widgets(): array {
return [
AttachmentStats::make(),
];
}
<!-- Single image -->
<x-laravel-attachment-library-image :src="$product->featured_image" />
<!-- Thumbnail -->
<x-laravel-attachment-library-image :src="$image" width="100" height="100" />
<x-laravel-attachment-library-image :src="$image" width="300" height="200" />
php artisan vendor:publish --tag="filament-attachment-library-views"
resources/js/plugin.js and rebuild:
npm run build
Tailwind Styling Requirement:
theme.css includes @source and the theme is registered in PanelProvider:
->theme('custom-theme')
Disk Conflicts:
public disk may cause conflicts with other files.attachments) in filesystems.php and set it in .env:
ATTACHMENTS_DISK=attachments
Base Path Overrides:
Relationship Caching:
refresh():
$product->load('gallery');
Glide Configuration:
glide.php is configured and the disk is accessible:
'driver' => 'public',
'source' => storage_path('app/public'),
Log Attachment Paths:
AttachmentService to verify storage:
\Log::debug('Attachment path:', [$attachment->path]);
Check Disk Permissions:
chmod -R 755 storage/app/attachments
Validate MIME Types:
dd($request->file()->getMimeType()) to debug uploads.Clear Filament Cache:
php artisan filament:clear-cache
Custom Storage Engines:
VanOns\LaravelAttachmentLibrary\Contracts\AttachmentStorage to support S3, Dropbox, etc.Event Listeners:
attachment.created, attachment.deleted, etc., to trigger actions:
use VanOns\LaravelAttachmentLibrary\Events\AttachmentCreated;
event(new AttachmentCreated($attachment));
Custom Fields:
AttachmentField to add features like:
Widget Customization:
AttachmentStats to display custom metrics (e.g., "Total Storage Used").attachment-library.php:
max_file_size (in MB) or allowed_mime_types.'max_file_size' => 10, // 10MB
'allowed_mime_types' => ['image/*', 'application/pdf'],
Glide Integration:
'glide' => [
'enabled' => false,
]
Navigation Group:
FilamentAttachmentLibrary::make()->navigationLabel('Media Library')
Asset Publishing:
How can I help you explore Laravel packages today?