Show custom page when email verification link expired

Using Laravel 10 with Breeze + Blade starter kit

For Breeze + Livewire + Alpine starter kit, see the section at the end

This is how you might change the default breeze installation to show a custom page when the signature in an account verification email has expired;

find the below in routes\auth.php

routes\auth.web
    Route::get('verify-email/{id}/{hash}', VerifyEmailController::class)
                ->middleware(['signed', 'throttle:6,1'])
                ->name('verification.verify');

remove the signed middleware

    Route::get('verify-email/{id}/{hash}', VerifyEmailController::class)
                ->middleware(['throttle:6,1'])
                ->name('verification.verify');

In the VerifyEmailController, add the following before the existing code;

        if (! $request->hasValidSignature()) {
            return redirect()->route('invalidSignature');
        }

This moves the signature checking from the middleware into the controller so that we can take control of the response. Here we redirect the user to a new view of our own design.

Duplicate the file resources/views/auth/verify-email.blade into verify-invalid.blade.php

Change it as below (only the message in the first div changes);

<x-guest-layout>
    <div class="mb-4 text-sm text-gray-600">
        {{ __('Sorry but that verification link is no longer valid, click below to request a new one.') }}
    </div>

    @if (session('status') == 'verification-link-sent')
        <div class="mb-4 text-sm font-medium text-green-600">
            {{ __('A new verification link has been sent to the email address you provided during registration.') }}
        </div>
    @endif

    <div class="flex items-center justify-between mt-4">
        <form method="POST" action="{{ route('verification.send') }}">
            @csrf

            <div>
                <x-primary-button>
                    {{ __('Resend Verification Email') }}
                </x-primary-button>
            </div>
        </form>

        <form method="POST" action="{{ route('logout') }}">
            @csrf

            <button type="submit" class="text-sm text-gray-600 underline rounded-md hover:text-gray-900 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500">
                {{ __('Log Out') }}
            </button>
        </form>
    </div>
</x-guest-layout>

Create a new route in auth.php

    Route::view('verify-invalid', 'auth.verify-invalid')
                ->name('invalidSignature');

This adds a new route that can show our new page.

For Breeze with Livewire+Alpine

The main difference to the above process is that the view to copy is located in resources/views/livewire/pages/auth/verify-email.blade.php

Remember that the default behaviour is that the user must be logged in when checking the verification email since the routes are wrapped in auth middleware

Last updated

Was this helpful?