Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

schwartzmj's avatar

Proper way to disable Personal Teams in Jetstream?

I'd like to disable the creation of a "Personal Team" and force the user to either create a team or be invited to a team.

Here's what I've changed to make this work, so far:

Within \App\Actions\Fortify > CreateNewUser > create(), I've removed the creation of a personal team:

    public function create(array $input)
    {
        Validator::make($input, [
            'name' => ['required', 'string', 'max:255'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', new Password, 'confirmed'],
        ])->validate();

        return DB::transaction(function () use ($input) {
            return User::create([
                'name' => $input['name'],
                'email' => $input['email'],
                'password' => Hash::make($input['password']),
            ]);
        });
//        return DB::transaction(function () use ($input) {
//            return tap(User::create([
//                'name' => $input['name'],
//                'email' => $input['email'],
//                'password' => Hash::make($input['password']),
//            ]),
//                function (User $user) {
//                $this->createTeam($user);
//            });
//        });
    }

However it looks like vendor/laravel/jetstream/src/HasTeams.php forces a currentTeam value of the user's Personal Team if they do not currently have a selected team.

    /**

     * Get the current team of the user's context.

     */

    public function currentTeam()

    {

        if (is_null($this->current_team_id)) {

            $this->forceFill([

                'current_team_id' => $this->personalTeam()->id,

            ])->save();

        }

 

        return $this->belongsTo(Jetstream::teamModel(), 'current_team_id');

    }

This seems like an issue since it is directly hardcoded within the Jetstream package. Should I search for uses of personalTeam and override various methods of the Jetstream package somehow?

0 likes
11 replies
Snapey's avatar
Snapey
Best Answer
Level 122

TBH teams seems a bit v0.1 at the moment

You may need to accept that the user will get a personal team, detect that and get the user to 'create' a team but actually just rename the personal team.

schwartzmj's avatar

That makes sense. Maybe I can go the other way and when I check the user's teams, ignore any personal teams.

mass6's avatar

What you can do is overwrite the isCurrentTeam() and currentTeam() methods.

Override the isCurrentTeam() method to first check if the user belongs to any team. If not, then return false early. Otherwise, get the user's current team and check if it's the same as the given team.

Override the currentTeam() method to set the current team if not already set. This can simply be the first team the user belongs to, or use some custom logic to determine the team to set the user to. In this example, it just uses the user's first team. Note that calling this method assumes that the user belongs to at least one team, but Jetstream only calls it from the isCurrentTeam() method.

// User model

/**
     * Determine if the user belongs to any team.
     * 
     * @return bool
     */
    public function hasTeams()
    {
        return $this->allTeams()->isNotEmpty();
    }

    /**
     * Determine if the given team is the current team.
     *
     * @param  mixed  $team
     * @return bool
     */
    public function isCurrentTeam($team)
    {
        if (! $this->allTeams()->count()) {
            return false;
        }

        return $team->id === $this->currentTeam->id;
    }

    /**
     * Get the current team of the user's context.
     */
    public function currentTeam()
    {
        if (is_null($this->current_team_id) && $this->id) {
            $this->switchTeam($this->allTeams()->first());
        }
        return $this->belongsTo(Jetstream::teamModel(), 'current_team_id');
    }

Then in navigation-dropdown.blade.php, wrap the Team Settings and Switch Teams links in conditionals that check and render the component only if the user belongs to any team at all.

<!-- Team Settings -->
@if (Auth::user()->hasTeams())
    <x-jet-dropdown-link href="{{ route('teams.show', Auth::user()->currentTeam->id) }}">
        {{ __('Team Settings') }}
    </x-jet-dropdown-link>
@endif


@if (Auth::user()->hasTeams())
    <!-- Team Switcher -->
    <div class="block px-4 py-2 text-xs text-gray-400">
      {{ __('Switch Teams') }}
    </div>
@endif
1 like
Sairahcaz's avatar

Thanks for that, thats exactly what I was looking for!

cjholowatyj's avatar

This is awesome! Is there a way to publish the vendor/laravel/jetstream/src folder so I can edit it safely in my project without the looming threat of it being overwritten? I'm not seeing anything in the vendor:publish list that looks like it does...

1 like
virgiltu's avatar

I think the odd thing is that a user has to create a team even when hes invited. If I invite a user to my team why does he needs to have his own also. Invitation should add users only to teams that they are invited to, if they want to create their own than be it. But code above helped me as I now look for the team they were invited to and just add them there.

3 likes
dbibancos's avatar

It works. I'm very thankful for Nick's instructions. The post was moved and can now be found at: https://npratley.net/disabling-personal-teams-in-laravel-8-and-jetstream The instructions are just missing one step: you need to register app/Traits on your composer.json. Otherwise the customer trait HasNoPersonalTeam will not be found. It will look like this:

    "autoload": {
        "psr-4": {
            "App\": "app/",
            "App\Traits\": "app/Traits/",
            "Database\Factories\": "database/factories/",
            "Database\Seeders\": "database/seeders/"
        }
    },
2 likes
Nsidhaye's avatar

Someone might get a lot information from github closed issue. It's good discussion & valid workaorunds.

https://github.com/laravel/jetstream/issues/117

I hope someday JetStream will make official option of enable / disable personal teams.

Most of my usecase needs only one admin need to create personal team and some times more than one personal team. Every user :(

INDEV's avatar

is it possible to just disable the create personalTeam() and just to assign user to a Users Team created by admin beforehand? So every new user that is registering gets assigned to the default Users team.

protected function createTeam(User $user): void
    {
        $user->ownedTeams()->save(Team::forceCreate([
            'user_id' => $user->id,
            // 'name' => explode(' ', $user->name, 2)[0]."'s Team", // this would create User's Team
           //  'name' => "User", // This would create a User Team for every new user
            'personal_team' => false, // disables user team
        ]));
    }

is there a prebuilt / propper way to assign every new user to a default team? Thanks in advance

1 like

Please or to participate in this conversation.