Introduction
Filament’s plugin system allows you to package and distribute reusable functionality. Plugins can register resources, pages, widgets, themes, and more. They provide a clean way to extend Filament panels with custom features.Understanding the Plugin interface
All Filament plugins implement theFilament\Contracts\Plugin interface:
getId()- Returns a unique identifier for the pluginregister()- Called when the plugin is registered with a panelboot()- Called after all plugins are registered
Creating a basic plugin
Plugin configuration
Make your plugins configurable with a fluent API:Static make() method
Add a staticmake() method for convenience:
Registering resources and pages
Plugins can register complete CRUD interfaces:Adding navigation items
Customize panel navigation from your plugin:Using render hooks
Inject custom content into the panel:panels::head.start- Start of<head>panels::head.end- End of<head>panels::body.start- Start of<body>panels::body.end- End of<body>panels::page.start- Start of page contentpanels::page.end- End of page contentpanels::sidebar.nav.start- Start of sidebar navigationpanels::sidebar.nav.end- End of sidebar navigation
Registering theme customizations
Plugins can customize the panel theme:Middleware and authentication
Plugins can register middleware:Using the boot() method
Theboot() method is called after all plugins are registered:
Service provider integration
Create a Laravel service provider for your plugin package:Complete plugin example
Here’s a comprehensive example of a feature-rich plugin:Testing plugins
Test your plugins to ensure they work correctly:Publishing your plugin
When distributing your plugin:- Create a comprehensive README.md with installation instructions
- Add proper versioning following semantic versioning
- Include a LICENSE file
- Provide migration files if your plugin needs database tables
- Document all configuration options
- Include screenshots or demos
- Add tests for core functionality
- Publish to Packagist for easy installation
Best practices
- Use descriptive plugin IDs that won’t conflict with others
- Make plugins configurable rather than hard-coding values
- Provide sensible defaults for all configuration options
- Use the
register()method for panel configuration - Use the
boot()method for initialization that needs all plugins loaded - Version your plugin assets to prevent caching issues
- Follow PSR-4 autoloading standards
- Namespace your views, translations, and config files
- Document all public methods and configuration options
- Provide migration files for database changes
- Test your plugin with multiple Filament versions
- Use dependency injection via
app()instead ofnew - Never use abbreviated variable names