amjadiqbal/filament-url-image-uploader
composer require amjadiqbal/filament-url-image-uploader in your project.php artisan vendor:publish --provider="Amjadiqbal\FilamentUrlImageUploader\FilamentUrlImageUploaderServiceProvider" to publish assets (if needed).use Amjadiqbal\FilamentUrlImageUploader\UrlImageUploader;
UrlImageUploader::make('image')
->directory('images')
->required()
->maxSize(5) // MB
->allowedExtensions(['jpg', 'png', 'svg']);
Usage section for basic implementation.config/filament-url-image-uploader.php for global defaults.Form Integration:
// In a Filament Resource Form
public static function form(Form $form): Form
{
return $form
->schema([
UrlImageUploader::make('hero_image')
->directory('products/{$record->id}')
->rules(['required', 'image']),
]);
}
Dynamic Directories: Use closures for dynamic paths:
UrlImageUploader::make('avatar')
->directory(fn (UploadedFile $file, ?Post $record) => "users/{$record->id}/avatars")
Model Binding:
public function getImageUrlAttribute(): ?string
{
return $this->image ? Storage::url($this->image) : null;
}
protected function castImage(): Attribute
{
return Attribute::make(
get: fn ($value) => is_array($value) ? $value['image'] : $value,
set: fn ($value) => is_array($value) ? $value : ['image' => $value],
);
}
Validation: Combine with Filament’s built-in validation:
UrlImageUploader::make('thumbnail')
->rules([
'required',
'image',
'dimensions:min_width=100,max_width=2000',
]);
'disk' => 's3',
->previewHeight(200) to control thumbnail size in the UI.FileUpload) for hybrid workflows:
$form->schema([
UrlImageUploader::make('remote_image'),
FileUpload::make('local_image'),
]);
Directory Permissions:
storage:link if accessing via public path.Permission denied errors when saving files.URL Validation:
ftp://).?width=500). Use ->allowQueryStrings() to bypass.beforeValidate:
$form->beforeValidate(function (Form $form) {
$form->fillFormData([
'image' => strtok($form->data['image'], '?'),
]);
});
Caching Issues:
->previewUrl(fn ($record) => $record->image_url . '?t=' . time())
Model Sync:
hasMany relationships, ensure the uploader’s directory includes the relationship key:
->directory("posts/{$record->id}/attachments")
->afterStateUpdated(fn ($state, $set) => \Log::debug('Uploaded:', $state))
ls storage/app/images/
telescope: Enable Laravel Telescope to inspect HTTP requests to remote URLs.Custom Validation: Override validation logic via a service provider:
UrlImageUploader::extend(function (UrlImageUploader $component) {
$component->validationRules = [
'required',
'url',
'image', // Custom rule to check remote image
];
});
Post-Processing:
Use afterUploaded to trigger actions (e.g., generate thumbnails):
->afterUploaded(fn ($record, $state) => \Image::make($state['image'])->resize(300, 200)->save())
Localization:
Extend translations via config/filament-url-image-uploader.php:
'labels' => [
'image_url' => 'Remote Image URL',
],
Headless Mode: Disable the preview UI for API-only forms:
->previewable(false)
->hiddenLabel()
->columnSpanFull()
How can I help you explore Laravel packages today?