3x1io/filament-browser
Filament Browser adds a file manager to Filament panels, letting you browse directories, upload and preview files, and manage media right from your admin UI. Works with local or cloud disks and integrates smoothly into any Filament resource or page.
The package is a Filament plugin that mounts a file browser/manager page inside a panel. Install and register it, then hit the page once to confirm your disk wiring is correct.
composer require 3x1io/filament-browser
php artisan vendor:publish --tag="filament-browser-config"
php artisan vendor:publish --tag="filament-browser-lang" # new in 1.0.2
php artisan storage:link
Register the plugin on the panel you want the browser in:
use ThreeX1IO\FilamentBrowser\FilamentBrowserPlugin;
public function panel(Panel $panel): Panel
{
return $panel
->plugin(FilamentBrowserPlugin::make());
}
Look first at config/filament-browser.php — that is where the storage disk, root path, and (as of 1.0.2) hidden-file behaviour are decided. The plugin's page class and routes are the second stop if you need to override behaviour.
First real use case: open the browser page, create a folder, upload a file, and confirm it lands in the configured disk. If the listing is empty, the problem is almost always disk/root config or the storage:link, not the plugin.
Panel-scoped registration. Register the plugin only on the panel where it belongs. Because registration is per-panel, you can wire a full-access browser on an internal admin panel and a read-only/limited one elsewhere without forking the plugin.
Disk abstraction. Point the config at a Laravel disk (local, public, s3, etc.) rather than a raw path. Everything downstream — URLs, previews, deletes — follows the disk's driver, so switching to S3 is config-only. Prefer a dedicated disk with its own root over public for anything user-uploaded.
Locking it down. The browser is a filesystem UI; treat it like a privileged admin tool. Gate it with canAccess()/policies on the Filament user, and restrict allowed extensions and max upload size in config. In production, consider registering the plugin conditionally:
->plugin(FilamentBrowserPlugin::make()->visible(fn () => auth()->user()?->is_admin))
Translations (1.0.2). Publish the lang files and add/edit keys per locale instead of hardcoding strings in an extended page. If a locale falls back to English, the published files are the place to add the missing keys — no need to touch package source.
Hidden files and folders (1.0.2). Toggle dotfile visibility through config rather than filtering in a custom page. Keep it off by default: exposing .env, .git, or storage metadata to a browsing UI is a footgun.
Reacting to saves (1.0.2). The new saved event lets you hook the browser into your app without forking: invalidate caches, generate thumbnails, queue a virus scan, or write an audit log. Register a listener and keep the handler idempotent — saves can be re-triggered by repeated edits.
Extending the page. For custom columns, previews, or extra toolbar actions, subclass the plugin's page and repoint the route in config rather than editing vendor files. This survives upgrades.
php artisan storage:link; a missing link shows as broken previews, not a helpful error.php artisan config:clear (and optimize:clear in deployed environments). Stale caches look like "the new hidden-files feature does nothing."storage/ and the disk root permissions before blaming the package... traversal and sensitive files are unreachable at the filesystem level, not just the UI.composer update, re-publish lang files if new keys were added, and diff the published config — new options (hidden files) ship with defaults you may want to override explicitly.How can I help you explore Laravel packages today?