Updated June 2026. Tested on Laravel 13 and PHP 8.4.

Laravel sends a perfectly fine password reset email out of the box, but it is plain and unbranded. When a reader asked how to replace it with their own design, here is the clean way: override the notification that the User model sends.

A custom notification

Create a notification that extends Laravel's built in ResetPassword, and override toMail to use your own view or your own message.

namespace App\Notifications;

use Illuminate\Auth\Notifications\ResetPassword;
use Illuminate\Notifications\Messages\MailMessage;

class ResetPasswordNotification extends ResetPassword
{
    public function toMail($notifiable): MailMessage
    {
        $url = url(route('password.reset', [
            'token' => $this->token,
            'email' => $notifiable->getEmailForPasswordReset(),
        ], false));

        return (new MailMessage)
            ->subject('Reset your password')
            ->markdown('emails.reset-password', ['url' => $url]);
    }
}

Using ->markdown(...) lets you write a nice email with Laravel's mail components. If you would rather use a plain Blade view, swap it for ->view('emails.reset-password', ['url' => $url]).

Tell the User model to use it

The User model decides which notification to send for a reset. Override sendPasswordResetNotification to send yours.

namespace App\Models;

use App\Notifications\ResetPasswordNotification;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

class User extends Authenticatable
{
    use Notifiable;

    public function sendPasswordResetNotification($token): void
    {
        $this->notify(new ResetPasswordNotification($token));
    }
}

Write the email template

Create the view you referenced. With the markdown components it can look like this.

{{-- resources/views/emails/reset-password.blade.php --}}
<x-mail::message>
# Reset your password

You asked to reset your password. Click below to choose a new one. This link expires in 60 minutes.

<x-mail::button :url="$url">
Reset Password
</x-mail::button>

If you did not request this, you can ignore this email.

Thanks,<br>
{{ config('app.name') }}
</x-mail::message>

That is it. From now on, every reset email uses your template and your branding, while Laravel still handles generating the token, expiring it, and verifying the reset. Questions welcome in the comments.