laravel-media-gallery maintained by atikhasan2090
Laravel Media Gallery & File Manager
A modern, highly performant, and UX-friendly Media Gallery & File Manager package for Laravel. Designed as a drop-in, modern replacement for legacy file managers like unisharp/laravel-filemanager, offering polymorphic image reuse across any model, rich SEO metadata (Alt Text, Title, Captions), and zero-conflict Blade & Vue.js components.
🚀 Key Features
- Infinite Image Reuse: Upload an image once and attach it anywhere (Products, Categories, Logos, Banners, Blog Posts, POS Quick-Buttons, User Avatars).
- SEO & Accessibility Ready: Manage Alt Text, Title, Caption, and Description with live inline auto-saving.
- Universal Component Support:
- Blade Component:
<x-media-gallery-picker>with instant thumbnail preview and remove button. - Vue.js Component:
<media-picker>supporting both Vue 2 and Vue 3. - Direct JavaScript API:
window.MediaGallery.open({...})for custom triggers, TinyMCE, CKEditor, Summernote, and TipTap.
- Blade Component:
- Zero CSS Conflicts: All styles are strictly scoped under
.lmg-*prefixes. Safely use it alongside Bootstrap 4/5, Tailwind CSS, or Element UI without broken layouts. - SaaS / Multi-Tenancy Ready: Automatically scopes media files and folders per tenant or user.
- Smart Image Transformation: Automatic thumbnail generation (thumb, medium, large), optional WebP conversion, and in-browser cropping/resizing.
- Folders & Organization: Create and manage folders to keep assets clean and organized.
- Drag & Drop Upload: Multi-file queue with real-time percentage progress bars.
📦 Requirements
- PHP:
^8.0 || ^8.1 || ^8.2 || ^8.3 - Laravel Framework:
^8.0 || ^9.0 || ^10.0 || ^11.0
🛠️ Installation
1. Require via Composer
Once published to Packagist:
composer require atikhasan2090/laravel-media-gallery
Testing locally in your existing project before publishing: In your application's
composer.json(e.g. inakaar-pos-blade), add a path repository:"repositories": [ { "type": "path", "url": "../../../My Personal Projects/laravel-media-gallery" } ]Then run:
composer require atikhasan2090/laravel-media-gallery:dev-master
2. One-Command Setup
Run the interactive installer to publish the config, migrations, and assets:
php artisan media-gallery:install
Or publish manually:
php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-config"
php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-migrations"
php artisan vendor:publish --provider="Atikhasan\MediaGallery\MediaGalleryServiceProvider" --tag="media-gallery-assets"
php artisan storage:link
php artisan migrate
🎨 Asset Setup
Add the styles and scripts to your admin layout (e.g. resources/views/layouts/app.blade.php):
<head>
<!-- Your existing CSS (Bootstrap, Tailwind, etc.) -->
@mediaGalleryStyles
</head>
<body>
<!-- Your Admin Content -->
<!-- Before closing body tag -->
@mediaGalleryScripts
</body>
🖥️ Usage in Blade Forms
Single Image Picker (e.g., Category Image, Logo, Avatar)
<x-media-gallery-picker
name="image_id"
:value="$category->image_id"
label="Category Image"
/>
Multiple Image Picker (e.g., Product Gallery)
<x-media-gallery-picker
name="gallery_images"
:value="$product->getMedia('gallery')->pluck('id')->toArray()"
multiple="true"
label="Product Gallery"
/>
⚡ Usage in Vue.js (Vue 2 & Vue 3)
Import and register the component in your app.js:
import MediaPicker from 'path-to-vendor/laravel-media-gallery/resources/js/components/MediaPicker.vue';
// Vue 2
Vue.component('media-picker', MediaPicker);
// Or Vue 3
app.component('media-picker', MediaPicker);
Then in your Vue template:
<!-- Single Image -->
<media-picker
v-model="form.thumbnail_id"
label="Product Thumbnail"
:preview="form.thumbnail_url"
/>
<!-- Multiple Images -->
<media-picker
v-model="form.gallery_ids"
:multiple="true"
label="Product Gallery Images"
/>
🗄️ Eloquent Model Integration (HasMedia Trait)
Add the HasMedia trait to any Model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Atikhasan\MediaGallery\Traits\HasMedia;
use Atikhasan\MediaGallery\Contracts\HasMediaInterface;
class Product extends Model implements HasMediaInterface
{
use HasMedia;
// ...
}
Attaching & Managing Media:
// Attach a single thumbnail
$product->attachMedia($request->thumbnail_id, 'thumbnail');
// Sync multiple gallery images (replaces existing under 'gallery')
$product->syncMedia($request->gallery_ids, 'gallery');
// Retrieve media
$thumbnailUrl = $product->getFirstMediaUrl('thumbnail'); // Full URL
$mediumThumb = $product->getFirstMediaUrl('thumbnail', 'medium'); // Medium size
$altText = $product->getFirstMediaAlt('thumbnail', 'Default Product Title');
// Retrieve all gallery items
$galleryItems = $product->getMedia('gallery');
foreach ($galleryItems as $media) {
echo $media->url;
echo $media->alt_text;
}
// Detach media
$product->detachMedia(null, 'gallery'); // Detach all gallery images
🌐 JavaScript API (WYSIWYG / Custom Triggers)
You can trigger the media picker from any button, WYSIWYG editor (TinyMCE, CKEditor, Summernote), or script:
window.MediaGallery.open({
multiple: false,
onSelect: function(item) {
console.log('Selected Media:', item);
// item contains:
// item.id
// item.url
// item.thumbnail_url
// item.alt_text
// item.title
// item.readable_size
}
});
🏢 SaaS & Multi-Tenancy Configuration
In config/media-gallery.php:
'multi_tenancy' => [
'enabled' => true,
'tenant_column' => 'tenant_id',
'tenant_resolver' => function() {
return auth()->user()->tenant_id;
},
'scope_by_user' => false,
],
When enabled, uploaded media and folders are completely isolated per tenant.
📄 Standalone Media Manager
Users can access the full standalone dashboard by navigating to:
http://your-app.test/media-gallery
(Route prefix and middleware are fully customizable in config/media-gallery.php).
🧪 Testing
composer test
📜 License
The MIT License (MIT). Please see LICENSE.md for more details.