mansoor/filament-unsplash-picker
Installation
composer require mansoor/filament-unsplash-picker
Publish the config (if needed):
php artisan vendor:publish --provider="Mansoor\FilamentUnsplashPicker\FilamentUnsplashPickerServiceProvider"
Configure Unsplash API
Add your Unsplash client_id to .env:
UNSPLASH_CLIENT_ID=your_unsplash_client_id_here
Ensure it’s reflected in config/services.php:
'unsplash' => [
'client_id' => env('UNSPLASH_CLIENT_ID'),
],
First Use Case Attach the picker to a Filament form field in a resource:
use Mansoor\FilamentUnsplashPicker\Fields\UnsplashPicker;
public static function form(Form $form): Form
{
return $form
->schema([
UnsplashPicker::make('image')
->label('Unsplash Image')
->required(),
]);
}
Basic Image Selection
Use the UnsplashPicker field directly in a Filament form:
UnsplashPicker::make('hero_image')
->label('Hero Banner')
->columnSpanFull()
->required();
Customizing Query Parameters Filter results by query terms or collections:
UnsplashPicker::make('background')
->query('nature, landscape')
->collections(['123456', '789012']) // Unsplash collection IDs
->perPage(20);
Handling Image Sizes
Specify the desired image size (default: regular):
UnsplashPicker::make('thumbnail')
->size('small') // Options: 'small', 'regular', 'large'
->previewHeight(150);
Integration with Media Libraries Store the selected image URL in a model and display it:
// In your model
public function getImageUrlAttribute()
{
return $this->attributes['image_url'] ?? null;
}
// In your resource table
TextColumn::make('image_url')
->label('Image URL')
->copyable();
Validation and Defaults Add validation rules or set defaults:
UnsplashPicker::make('logo')
->rules(['required', 'image'])
->default('https://source.unsplash.com/random/800x600');
UnsplashPicker::make('banner')
->cacheResults(3600); // Cache for 1 hour
UnsplashPicker::make('icon')
->label(__('filament-unsplash-picker::fields.unsplash_picker.label'))
->placeholder(__('filament-unsplash-picker::fields.unsplash_picker.placeholder'));
UnsplashPicker::make('dynamic_image')
->livewire(); // If supported in future updates
Unsplash API Limits
429 Too Many Requests.UnsplashPicker::make('image')
->retryOnRateLimit(3); // Retry 3 times on 429
Missing Custom Theme
Image Size Mismatches
size parameter may return unexpected dimensions (e.g., regular isn’t always 1024x1024).->previewHeight() to constrain the display and handle resizing client-side.CORS Issues
Rate-Limited Searches
" " or null) may trigger rate limits.UnsplashPicker::make('image')
->defaultQuery('photography');
API Errors
400, 401, or 429 errors).config/filament.php:
'debug' => env('FILAMENT_DEBUG', false),
Field Not Rendering
client_id is set in .env and config/services.php.php artisan filament:cache-reset
Styling Issues
/* resources/css/filament/unsplash-picker.css */
.filament-unsplash-picker {
--wp-preview-height: 200px;
}
Custom API Client Extend the underlying Unsplash client for additional features:
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->extend('unsplash', function ($client) {
$client->withCustomHeader('X-Custom-Header', 'value');
return $client;
});
}
Add Metadata Fields
Fetch and store additional Unsplash metadata (e.g., author, download_location):
UnsplashPicker::make('featured_image')
->withMetadata(['author', 'download_location'])
->statePath('metadata');
Local Storage Fallback Allow users to upload local files if Unsplash fails:
UnsplashPicker::make('fallback_image')
->fallbackToFileUpload()
->fileUploadInstructions('Upload a local file if Unsplash fails.');
Event Listeners Listen for image selection events to trigger actions:
// In a service provider
UnsplashPicker::listen('image.selected', function ($imageUrl, $field) {
Log::info("Selected image: $imageUrl via field: {$field->getName()}");
});
Testing Mock the Unsplash API in tests:
use Mansoor\FilamentUnsplashPicker\Testing\TestsUnsplashPicker;
public function test_unsplash_picker()
{
TestsUnsplashPicker::fake([
'https://api.unsplash.com/search/photos' => [
'results' => [['urls' => ['regular' => 'fake-url.jpg']]],
],
]);
// Test your form...
}
How can I help you explore Laravel packages today?