ยท yebor974 ยท Getting Started, Tutorials

Email verification in Filament: UserResource filters and actions

Learn how to enable email verification in Filament, set up a UserResource, add filters for verified/unverified accounts, and create a resend verification action

Email verification in Filament - UserResource filters and actions - picture

Managing users effectively is at the heart of many applications. Filament provides powerful tools to create and customize resources. In this article, we will focus on:

  1. Enabling Email Verification on User
  2. Setting up a User resource.
  3. Adding filter and action for email verification.

Step 1: Enable email verification on User model and Filament panel

You need to implement MustVerifyEmail on your User model and add emailVerification on your Filament Panel Provider.

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

class User extends Authenticatable implements FilamentUser, MustVerifyEmail
{
    ...
}
class AdminPanelProvider extends PanelProvider
{
    public function panel(Panel $panel): Panel
    {
         return $panel
             ...
             ->login()
             ->registration()
             ->emailVerification()
             ...
    }
}

With this, when a user registers a new account, they will be asked to verify their email address. An email is automatically sent to them.

Step 2: Define the UserResource

Generate a resource for your User model:

php artisan make:filament-resource User

If you have more than one panel, you will be prompted to choose which one you want to create it in.

Update the resource configuration to include only the most relevant columns:

public static function table(Table $table): Table
{
    return $table
        ->columns([
            Tables\Columns\TextColumn::make('name')
                ->sortable()
                ->searchable(),
            Tables\Columns\TextColumn::make('email')
                ->sortable()
                ->searchable(),
            Tables\Columns\TextColumn::make('email_verified_at')
                ->label('Email Verified')
                ->dateTime('d m Y H:i'),
            Tables\Columns\TextColumn::make('created_at')
                ->label('Registered At')
                ->dateTime('d m Y H:i'),
        ]);
}

Step 3: Add filters to retrieve verified or unverified accounts

Use filters to help admins find users faster. For example, filter by email verification status:

public static function table(Table $table): Table
{
    return $table
        ...
        ->filters([
            Tables\Filters\Filter::make('verified')
                ->label('Email Verified')
                ->query(fn (Builder $query) => $query->whereNotNull('email_verified_at')),
            Tables\Filters\Filter::make('unverified')
                ->label('Email Not Verified')
                ->query(fn (Builder $query) => $query->whereNull('email_verified_at')),
        ]);
}
  • Filter::make('verified'): Retrieves accounts where the email_verified_at column is not null, indicating the email has been verified.
  • Filter::make('unverified'): Retrieves accounts where the email_verified_at column is null, indicating the email is unverified.

Also, you can use a ternary filter, which simplifies the process of filtering between null and not null values:

public static function table(Table $table): Table
{
    return $table
        ...
        ->filters([
            Tables\Filters\TernaryFilter::make('verified')
                ->label('Verified email')
                ->attribute('email_verified_at')
                ->nullable(),
        ]);
}

Step 3: Add a table action to resend verification email

Add a table action to resend the verification email for unverified user account:

use Filament\Notifications\Auth\VerifyEmail;
use Filament\Notifications\Notification;

public static function table(Table $table): Table
{
    return $table
        ...
        ->actions([
            Tables\Actions\EditAction::make(),
            Tables\Actions\Action::make('resend_verification_email')
                ->label('Resend Verification Email')
                ->icon('heroicon-o-envelope')
                ->authorize(fn(User $record) => !$record->hasVerifiedEmail())
                ->action(function (User $record) {
                    $notification = new VerifyEmail();
                    $notification->url = filament()->getVerifyEmailUrl($record);
                    $record->notify($notification);

                    Notification::make()
                        ->title("Verification email has been resent.")
                        ->send();
                })
                ->requiresConfirmation(),
        ]);
}
  • ->authorize(fn(User $record) => !$record->hasVerifiedEmail()): The action is only authorized if the user's email is not verified

This implementation is for the current panel. If the user is verified on another panel, you need to retrieve the correct URL like this: `filament()->getPanel('id_of_panel')->getVerifyEmailUrl($record);

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

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.