· yebor974 · Advanced Techniques, Tutorials, UI/UX Design
Branding in Filament multi-tenant: Customize logo & colors
Learn how to dynamically set logos and colors in a Filament multi-tenancy panel. Customize branding per tenant using middleware and database configurations.

Filament allows extensive customization of its panels, including branding elements like the logo and colors. In a multi-tenant application, such as a white-label app, you may want to display different logos depending on the active tenant. This article will guide you through dynamically setting the logo and branding for a Member
panel based on the connected tenant.
To manage a multi-tenant panel, you can follow this article. This guide builds upon that configuration.
Storing Tenant-Specific Branding
In your Entity
model (which represents a tenant for this article), define methods to retrieve the logo and colors dynamically (To simplify, we define only the primary color instead of a full color set):
class Entity extends Model
{
protected $fillable = [
//....
'logo',
'config',
];
protected $casts = [
'config' => 'json',
];
public function getBrandLogo()
{
if ($this->logo) {
return asset('private/' . $this->logo);
}
return asset('images/logo.svg'); // Default logo if none is set
}
public function getPrimaryColorCode()
{
return Arr::get($this->config, 'colors.primary', '#0099a8'); // Default primary color
}
//...
}
Here, we assume that:
- The
logo
attribute stores the tenant’s custom logo. - The
config
attribute (stored as JSON in the database) contains branding configurations, including colors.
You can manage these attributes on your EditEntityProfile
page with a FileUpload
and a ColorPicker
like this :
FileUpload::make('logo')
->image()
->imageEditor()
->disk('private')
->directory('logos')
->visibility('private'),
ColorPicker::make('config.colors.primary')
->nullable()
->hexColor(),
Setting a default logo in the Panel Provider
By default, Filament allows you to define a static logo in your PanelProvider
. In our example, this can be set in MemberPanelProvider.php
:
use App\Models\Entity;
use Filament\Panel;
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('member')
->tenant(Entity::class)
->brandLogo(asset('images/logo.svg')) // Default logo
->brandLogoHeight('7rem') // Logo height
//...
}
This ensures that if no tenant-specific logo is defined or if there is no active tenant (e.g., on the login page), the default logo will be used.
Adjusting the logo and colors dynamically
To modify the logo dynamically, we need to hook into Filament’s Tenancy middleware system. You can create a middleware, e.g., ApplyFilamentTenantThemeMiddleware.php
, and modify the logo and colors based on the active tenant.
Creating a middleware
You need this middleware to dynamically apply branding settings based on the active tenant, ensuring that each user sees the appropriate logo and colors without requiring manual configuration.
php artisan make:middleware Filament\\ApplyFilamentTenantThemeMiddleware
This command creates the middleware on App\Http\Middleware\Filament\
.
Changing the logo and colors based on Tenant
To change the logo and color scheme per tenant, first register the middleware on the MemberPanelProvider
:
use App\Models\Entity;
use Filament\Panel;
use App\Http\Middleware\Filament\ApplyFilamentTenantThemeMiddleware;
public function panel(Panel $panel): Panel
{
return $panel
->default()
->id('member')
->tenant(Entity::class)
->brandLogo(asset('images/logo.svg')) // Default logo
->brandLogoHeight('7rem') // Logo height
->tenantMiddleware([
ApplyFilamentTenantThemeMiddleware::class, //Registering tenant middleware
])
//...
}
Then, update the handle method in your middleware to apply the logo and colors dynamically:
use Closure;
use Filament\Facades\Filament;
use Filament\Support\Facades\FilamentColor;
use Illuminate\Http\Request;
class ApplyFilamentTenantThemeMiddleware
{
public function handle(Request $request, Closure $next)
{
$tenant = filament()->getTenant();
if (!$tenant) {
return $next($request);
}
// Set the tenant-specific logo
Filament::getCurrentPanel()->brandLogo($tenant->getBrandLogo());
Filament::getCurrentPanel()->brandLogoHeight('3.5rem');
// Set the tenant-specific primary color
if ($colors = Arr::get($tenant->config, 'colors')) {
FilamentColor::register([
'primary' => $tenant->getPrimaryColorCode()
]);
}
return $next($request);
}
}
-
Default logo and primary color on Login page:
-
Custom logo and primary color on panel:
Conclusion
By leveraging Filament’s middleware and panel customization features, you can create a fully dynamic branding system that adapts to each tenant. This approach guarantees that each tenant in your multi-tenant Filament application enjoys a unique and fully customized user experience.
Support my Work ☕
Writing in-depth tutorials like this takes time and effort. If you found this article helpful and want to support my work, consider buying me a coffee or sponsoring me on GitHub! Your support helps me keep creating valuable content for the community.
☕ Buy me a coffee | 💖 Sponsor me on GitHub
Thanks for reading and happy coding! 🚀