DEV Community

Cover image for Building a Laravel Filament Multi-Tenant Panel
yebor974 for Filament Mastery

Posted on • Originally published at filamentmastery.com

1 1 1 1 1

Building a Laravel Filament Multi-Tenant Panel

In modern application development, multi-tenancy is a crucial approach for SaaS solutions or applications shared across multiple entities. With Filament, a powerful administration tool for Laravel, setting up a robust and scalable multi-tenant system becomes straightforward.

In this guide, we will set up a multi-tenancy panel with Filament named Member. The tenant model will be Entity, and it will include a name field.

Security and role-based access will not be covered in this article but will be addressed in another one.

Step 1: Preparing the Entity Model

Start by creating the tenant model Entity. This model will only include a name field for simplicity. To manage users within each tenant, we will leverage the existing User model. We assume that a users table already exists.

php artisan make:model Entity -m
Enter fullscreen mode Exit fullscreen mode

Update the migration file for the entities table:

public function up(): void
{
    Schema::create('entities', function (Blueprint $table) {
        $table->id();
        $table->string('name');
        $table->timestamps();
    });

    Schema::create('entity_user', function (Blueprint $table) {
        $table->id();
        $table->unsignedBigInteger('user_id');
        $table->unsignedBigInteger('entity_id');
        $table->timestamps();
    });
}
Enter fullscreen mode Exit fullscreen mode

Update your Entity and User model to add associated relationship:

class Entity extends Model
{
     public function users(): BelongToMany
     {
        return $this->belongsToMany(
            User::class,
            'entity_user')
        )->withTimestamps();
     }
}

class User extends Model
{
     public function entities(): BelongToMany
     {
        return $this->belongsToMany(
            Entity::class,
            'entity_user')
        )->withTimestamps();
     }
}
Enter fullscreen mode Exit fullscreen mode

Run the migration:

php artisan migrate
Enter fullscreen mode Exit fullscreen mode

Step 2: Configure the User model for multi tenancy

We need to define some functions in our User model to implement the FilamentUser, HasTenants, and HasDefaultTenant interfaces:

use Filament\Models\Contracts\FilamentUser;
use Filament\Models\Contracts\HasDefaultTenant;
use Filament\Models\Contracts\HasTenants;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable implements FilamentUser, HasTenants, HasDefaultTenant 
{
    public function entities(): BelongToMany
    {
        return $this->belongsToMany(
            Entity::class,
            'entity_user')
        )->withTimestamps();
    }

    public function canAccessTenant(Model $tenant): bool
    {
        return $this->entities->contains($tenant);
    }

    public function getTenants(Panel $panel): array|Collection
    {
        return $this->entities ?? [];
    }

    public function getDefaultTenant(Panel $panel): ?Model
    {
        return $this->entities()->first();
    }
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Create a Tenant Registration page

To allow users to register new tenants, we will create a registration page by extending RegisterTenant.

php artisan make:filament-page RegisterTenant
Enter fullscreen mode Exit fullscreen mode

and choose the correct panel id (member for the example).

namespace App\Filament\Member\Pages;

use App\Models\Entity;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\Tenancy\RegisterTenant as BaseRegisterTenant;

class RegisterTenant extends BaseRegisterTenant
{
    public static function getLabel(): string
    {
        return 'Register your company';
    }

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                TextInput::make('name')
                    ->label('Name')
                    ->required()
                    ->maxLength(255),
            ]);
    }

    protected function handleRegistration(array $data): Entity
    {
        /** @var Entity $entity */
        $entity = parent::handleRegistration($data);

        /** @var User $user */
        $user = auth()->user();
        $user->entities()->attach($entity->id);

        return $entity;
    }
}
Enter fullscreen mode Exit fullscreen mode

This page allows users to register a new tenant with a simple name field. When user creates an account, he is automatically redirect to this registration process.

Step 4: Creating the Tenant Entity Profile Page

To allow to edit tenant profile, we will create a profile page by extending EditTenantProfile.

php artisan make:filament-page EditEntityProfile
Enter fullscreen mode Exit fullscreen mode

and choose the correct panel id (member for the example).

namespace App\Filament\Member\Pages;

use App\Models\Entity;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Form;
use Filament\Pages\Tenancy\EditTenantProfile;

class EditTenantProfile extends EditTenantProfile
{
    public static function getLabel(): string
    {
        return 'Edit your company';
    }

    public function form(Form $form): Form
    {
        return $form
            ->schema([
                TextInput::make('name')
                    ->label('Name')
                    ->required(),
            ]);
    }
}
Enter fullscreen mode Exit fullscreen mode

This page allows users to edit their current tenant with a simple name field.

Step 5: Add Tenant to panel

Now, we need to set panel as Tenant:

use App\Filament\Member\Pages\EditTenantProfile;
use App\Filament\Member\Pages\RegisterTenant;
use App\Models\Entity;
use Filament\Panel;

public function panel(Panel $panel): Panel
{
    return $panel
        ->default()
        ->id('member')
        ->tenant(Entity::class)
        ->tenantRegistration(RegisterTenant::class)
        ->tenantProfile(EditTenantProfile::class)
        ->tenantMenuItems([
            'register' => MenuItem::make()->label('New company'),
        ]),
        //...
}
Enter fullscreen mode Exit fullscreen mode
  • ->tenant(Entity::class) defines the tenant model.
  • ->tenantRegistration(RegisterTenant::class) defines the registration tenant page.
  • ->tenantProfile(EditTenantProfile::class) defines the edit tenant page.
  • ->tenantMenuItems([..]) permits to add menu items on the tenant menu on sidebar.
  • 'register' => MenuItem::make()->label('New company') permits user to add more tenant entities in our config. You dont need to add this line like Edit Tenant Profile page on tenantMenuItems, they are present by default. However, you can customize label here or other criteria like authorization.

Filament Mastery Register Tenant Page

Filament Mastery Tenant Dashboard Example

Filament Mastery Switch Tenant Example

Filament Mastery Edit Tenant Page

Top comments (0)

👋 Kindness is contagious

Discover fresh viewpoints in this insightful post, supported by our vibrant DEV Community. Every developer’s experience matters—add your thoughts and help us grow together.

A simple “thank you” can uplift the author and spark new discussions—leave yours below!

On DEV, knowledge-sharing connects us and drives innovation. Found this useful? A quick note of appreciation makes a real impact.

Okay