ยท 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
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:
- Enabling Email Verification on User
- Setting up a User resource.
- 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 theemail_verified_at
column is not null, indicating the email has been verified. -
Filter::make('unverified')
: Retrieves accounts where theemail_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);