· 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.

Branding in Filament multi-tenant: Customize logo & colors - picture

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: Filament Mastery Login Page

  • Custom logo and primary color on panel: Filament Mastery Tenant Panel Dashboard

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! 🚀

Avatar of yebor974
yebor974
Freelance - French IT Engineer passionate about Laravel and Filament PHP, creating innovative solutions to simplify web development.
React
Share post

Related Posts

View All Posts

Customize your Filament panel theme

Learn how to create and apply custom themes for Filament panels, including setting sidebar colors, defining primary colors, and customizing integrated elements.

Stay ahead in the Filament Mastery adventure

Join our community of Filament PHP enthusiasts! Get exclusive tips, tutorials, and updates delivered straight to your inbox.