Weave Code
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

Livewire Image Uploader Laravel Package

sherwinchia/livewire-image-uploader

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sherwinchia/livewire-image-uploader
    

    Publish the config (optional, for customization):

    php artisan vendor:publish --provider="Sherwinchia\LivewireImageUploader\LivewireImageUploaderServiceProvider"
    
  2. First Use Case: Add the component to a Blade file (e.g., edit-profile.blade.php):

    <livewire:image-uploader name="profileImages" multiple size="2048" />
    

    Bind the property in your Livewire component:

    use Sherwinchia\LivewireImageUploader\Http\Traits\ImageUploader;
    
    class ProfileComponent extends Component
    {
        use ImageUploader;
    
        public $profileImages = [];
    
        // ...
    }
    
  3. Key Files to Review:

    • config/livewire-image-uploader.php (for upload paths, allowed extensions, etc.)
    • resources/views/vendor/livewire-image-uploader (customize templates if needed).

Implementation Patterns

Core Workflows

  1. Single Upload:

    <livewire:image-uploader name="logo" />
    
    • Automatically stores filenames in $logo (array).
    • Handles drag-and-drop + file selection.
  2. Multiple Uploads with Preview:

    <livewire:image-uploader name="gallery" multiple />
    
    • Renders a grid of thumbnails for uploaded files.
    • Use $gallery in your component to access filenames (e.g., loop through and display images).
  3. Integration with Storage:

    • Uploaded files are saved to storage/app/public/uploads/{name}/ by default.
    • Access files via storage_link() in AppServiceProvider or use url('storage/uploads/...').
  4. Form Submission:

    public function save()
    {
        // Process $profileImages array (e.g., move files, update DB)
        $this->validate([
            'profileImages.*' => 'image|max:2048',
        ]);
    
        // Example: Store paths in DB
        $imagePaths = array_map(fn($name) => "uploads/{$this->name}/$name", $this->profileImages);
        // ...
    }
    
  5. Custom Templates: Override default views by publishing and modifying:

    php artisan vendor:publish --tag=livewire-image-uploader-views
    

    Key files:

    • preview.blade.php (customize thumbnails).
    • upload.blade.php (modify drag-and-drop area).

Advanced Patterns

  • Dynamic Upload Paths: Override the config path dynamically:

    config(['livewire-image-uploader.path' => "uploads/{$this->user->id}"]);
    
  • Validation: Extend validation in your component:

    protected $rules = [
        'profileImages.*' => 'image|mimes:jpeg,png|max:2048',
    ];
    
  • Remote Storage: Use Storage::disk('s3')->put(...) in a saved event to sync to S3 after upload.

  • Events: Listen for upload events in your component:

    protected $listeners = ['imageUploaded' => 'handleUpload'];
    
    public function handleUpload($name)
    {
        // Custom logic (e.g., generate thumbnails)
    }
    

Gotchas and Tips

Pitfalls

  1. File Permissions:

    • Ensure storage/app/public/uploads/ is writable:
      chmod -R 775 storage/app/public/uploads
      
    • Run php artisan storage:link if using storage_link().
  2. CSRF Token Mismatch:

    • If uploads fail silently, check for CSRF token issues. Ensure the Livewire component is within a form or uses @csrf.
  3. Memory Limits:

    • Large files (>2MB) may hit PHP’s upload_max_filesize or post_max_size. Adjust in php.ini or use chunked uploads (not supported natively; consider Dropzone.js as a fallback).
  4. Duplicate Filenames:

    • The package doesn’t rename duplicates. Handle collisions in your saved event:
      public function saved($name)
      {
          $path = "uploads/{$this->name}/" . pathinfo($name, PATHINFO_FILENAME) . '_' . time() . '.' . pathinfo($name, PATHINFO_EXTENSION);
          Storage::move("uploads/{$this->name}/$name", $path);
          // Update $this->name array with the new path
      }
      
  5. Livewire Property Binding:

    • Ensure the name prop matches a public property in your component. Private/protected properties won’t work.

Debugging Tips

  • Check Uploads Directory: Verify files are saved to storage/app/public/uploads/{name}/. If empty, check:

    • PHP error logs (storage/logs/laravel.log).
    • Browser console for JS errors (e.g., CORS, CSRF).
  • Log Events: Add debug logs in your component’s saved or deleted methods:

    public function saved($name)
    {
        \Log::info("Uploaded: {$this->name}/$name");
    }
    
  • Disable CSRF for Testing: Temporarily disable CSRF in App\Http\Middleware\VerifyCsrfToken to test uploads:

    protected $except = [
        'livewire/*',
    ];
    

    Re-enable for production!

Extension Points

  1. Custom Storage Engine: Override the upload method in the trait:

    use Sherwinchia\LivewireImageUploader\Http\Traits\ImageUploader as BaseImageUploader;
    
    class CustomImageUploader extends BaseImageUploader
    {
        protected function upload($file, $name)
        {
            // Custom logic (e.g., S3, local path manipulation)
            return $this->customStorage->save($file, $name);
        }
    }
    
  2. Add Metadata: Extend the saved event to process images (e.g., EXIF data):

    use Intervention\Image\Facades\Image;
    
    public function saved($name)
    {
        $path = storage_path("app/public/uploads/{$this->name}/$name");
        $img = Image::make($path)->resize(800, null, function ($constraint) {
            $constraint->aspectRatio();
        });
        $img->save($path);
    }
    
  3. Localization: Override translation strings in config/app.php:

    'livewire-image-uploader' => [
        'messages' => [
            'upload' => 'Subir imagen...',
            'remove' => 'Eliminar',
        ],
    ],
    
  4. Progress Bars: Use Livewire’s wire:model.live to track upload progress:

    <progress wire:model.live="uploadProgress"></progress>
    

    Update progress in your component:

    public $uploadProgress = 0;
    
    public function updatingUploadProgress($value)
    {
        $this->uploadProgress = $value;
    }
    
  5. Fallback for Older Browsers: Add a polyfill for URL.createObjectURL() if supporting IE11:

    <script>
        if (!window.URL) {
            window.URL = window.webkitURL || window.mozURL || window.msURL;
        }
    </script>
    
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.
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge