更新日:2025/10/27
Laravel Breeze Tutorial (Blade + Tailwind)
Laravel Breeze is a lightweight and elegant authentication starter kit for Laravel applications. It provides the essential features required for a modern authentication system using Blade templates and Tailwind CSS. Breeze is designed for developers who prefer simplicity, flexibility, and complete control over their code without the complexity of JavaScript-heavy stacks.
Breeze implements Laravel’s core authentication features, including registration, login, password reset, email verification, and password confirmation. It’s ideal for small and medium-sized applications, or as a foundation for more advanced setups.
Laravel Breeze is part of Laravel’s official starter kits (alongside Jetstream, Fortify, and Spark). It focuses on simplicity while maintaining Laravel’s elegant structure. Some key advantages include:
Before installing Laravel Breeze, ensure you have the following environment:
composer create-project laravel/laravel breeze-demo cd breeze-demo composer require laravel/breeze --dev Run the installation command and choose the Blade option when prompted:
php artisan breeze:install This command will:
npm install npm run dev php artisan migrate php artisan serve Now visit http://127.0.0.1:8000/register. You should see a clean, Tailwind-styled registration form ready to use.
After installation, Laravel Breeze sets up a few important files and directories to handle authentication. Let’s explore the main ones:
Located at app/Http/Controllers/Auth/, these controllers handle user login, registration, password reset, and logout.
Example — RegisteredUserController.php:
namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use App\Models\User; use Illuminate\Http\Request; use Illuminate\Support\Facades\Hash; use Illuminate\Validation\Rules; class RegisteredUserController extends Controller { public function create() { return view('auth.register'); } public function store(Request $request) { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:'.User::class], 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); auth()->login($user); return redirect()->intended(route('dashboard', absolute: false)); } } Breeze automatically registers authentication routes located in routes/auth.php and includes them in routes/web.php.
Route::get('/register', [RegisteredUserController::class, 'create']) ->middleware('guest') ->name('register'); Route::post('/register', [RegisteredUserController::class, 'store']) ->middleware('guest'); All the authentication views are located in resources/views/auth/.
Example — login.blade.php:
<x-guest-layout> <form method="POST" action="{{ route('login') }}"> @csrf <div> <x-input-label for="email" :value="__('Email')" /> <x-text-input id="email" type="email" name="email" class="block mt-1 w-full" required autofocus /> <x-input-error :messages="$errors->get('email')" class="mt-2" /> </div> <div class="mt-4"> <x-input-label for="password" :value="__('Password')" /> <x-text-input id="password" type="password" name="password" class="block mt-1 w-full" required autocomplete="current-password" /> <x-input-error :messages="$errors->get('password')" class="mt-2" /> </div> <div class="block mt-4"> <label for="remember_me" class="inline-flex items-center"> <input id="remember_me" type="checkbox" name="remember" class="rounded border-gray-300"> <span class="ml-2 text-sm text-gray-600">{{ __('Remember me') }}</span> </label> </div> <div class="flex items-center justify-end mt-4"> @if (Route::has('password.request')) <a class="underline text-sm text-gray-600 hover:text-gray-900" href="{{ route('password.request') }}"> {{ __('Forgot your password?') }} </a> @endif <x-primary-button class="ml-3"> {{ __('Log in') }} </x-primary-button> </div> </form> </x-guest-layout> Laravel Breeze leverages Laravel’s built-in authentication mechanisms powered by the Auth facade, guards, and middleware.
Here’s how the authentication process works:
namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; class AuthenticatedSessionController extends Controller { public function create() { return view('auth.login'); } public function store(Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (Auth::attempt($credentials, $request->boolean('remember'))) { $request->session()->regenerate(); return redirect()->intended('dashboard'); } return back()->withErrors([ 'email' => 'The provided credentials do not match our records.', ]); } public function destroy(Request $request) { Auth::logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/'); } } Laravel Breeze is intentionally minimal. However, it’s highly flexible and can be customized to match your project’s specific requirements. Let’s explore some of the most common customization techniques.
You can easily add extra fields to the registration form such as username, phone number, or role. Here’s how:
<!-- resources/views/auth/register.blade.php --> <x-guest-layout> <form method="POST" action="{{ route('register') }}"> @csrf <!-- Name --> <div> <x-input-label for="name" :value="__('Name')" /> <x-text-input id="name" class="block mt-1 w-full" type="text" name="name" required autofocus autocomplete="name" /> <x-input-error :messages="$errors->get('name')" class="mt-2" /> </div> <!-- Username --> <div class="mt-4"> <x-input-label for="username" :value="__('Username')" /> <x-text-input id="username" class="block mt-1 w-full" type="text" name="username" required autocomplete="username" /> <x-input-error :messages="$errors->get('username')" class="mt-2" /> </div> <!-- Email Address --> <div class="mt-4"> <x-input-label for="email" :value="__('Email')" /> <x-text-input id="email" class="block mt-1 w-full" type="email" name="email" required autocomplete="username" /> <x-input-error :messages="$errors->get('email')" class="mt-2" /> </div> <!-- Password --> <div class="mt-4"> <x-input-label for="password" :value="__('Password')" /> <x-text-input id="password" class="block mt-1 w-full" type="password" name="password" required autocomplete="new-password" /> <x-input-error :messages="$errors->get('password')" class="mt-2" /> </div> <!-- Confirm Password --> <div class="mt-4"> <x-input-label for="password_confirmation" :value="__('Confirm Password')" /> <x-text-input id="password_confirmation" class="block mt-1 w-full" type="password" name="password_confirmation" required /> <x-input-error :messages="$errors->get('password_confirmation')" class="mt-2" /> </div> <div class="flex items-center justify-end mt-4"> <x-primary-button class="ml-4"> {{ __('Register') }} </x-primary-button> </div> </form> </x-guest-layout> Then update the controller:
// app/Http/Controllers/Auth/RegisteredUserController.php public function store(Request $request) { $request->validate([ 'name' => 'required|string|max:255', 'username' => 'required|string|max:255|unique:users', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|confirmed|min:8', ]); $user = User::create([ 'name' => $request->name, 'username' => $request->username, 'email' => $request->email, 'password' => Hash::make($request->password), ]); Auth::login($user); return redirect(RouteServiceProvider::HOME); } If your app requires roles (like admin, editor, user), you can integrate Spatie Laravel Permission or build a simple enum-based role system. Here’s a lightweight example:
// database/migrations/add_role_to_users_table.php Schema::table('users', function (Blueprint $table) { $table->string('role')->default('user'); }); Then in your User model:
// app/Models/User.php public function isAdmin() { return $this->role === 'admin'; } In your route or controller, you can now easily restrict access:
Route::get('/admin', function () { abort_unless(Auth::user()?->isAdmin(), 403); return view('admin.dashboard'); }); Because Laravel Breeze ships with Tailwind CSS, styling is straightforward. You can easily add components and modify layout files.
<div class="bg-white rounded-lg shadow-md p-6"> <h2 class="text-xl font-semibold mb-4">Welcome Back!</h2> <p class="text-gray-600">You're logged in as {{ Auth::user()->name }}.</p> </div> Let’s look under the hood and understand how Breeze handles authentication in Laravel.
// app/Http/Controllers/Auth/AuthenticatedSessionController.php public function store(Request $request) { $credentials = $request->validate([ 'email' => ['required', 'email'], 'password' => ['required'], ]); if (Auth::attempt($credentials, $request->boolean('remember'))) { $request->session()->regenerate(); return redirect()->intended(RouteServiceProvider::HOME); } return back()->withErrors([ 'email' => 'The provided credentials do not match our records.', ]); } public function destroy(Request $request) { Auth::guard('web')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/'); } Laravel Breeze includes password reset functionality by default. It uses Laravel’s built-in Password::sendResetLink and Password::reset methods.
// app/Http/Controllers/Auth/PasswordResetLinkController.php public function store(Request $request) { $request->validate(['email' => 'required|email']); $status = Password::sendResetLink( $request->only('email') ); return $status === Password::RESET_LINK_SENT ? back()->with('status', __($status)) : back()->withErrors(['email' => __($status)]); } Although Breeze uses Blade Tailwind by default, you can gradually enhance your app with Alpine.js for interactivity.
<div x-data="{ show: false }" class="relative"> <x-input-label for="password" :value="__('Password')" /> <input :type="show ? 'text' : 'password'" name="password" id="password" class="block mt-1 w-full"> <button type="button" @click="show = !show" class="absolute inset-y-0 right-0 px-3"> <span x-text="show ? 'Hide' : 'Show'"></span> </button> </div> | Feature | Breeze | Jetstream | Fortify |
|---|---|---|---|
| UI Layer | Blade Tailwind | Livewire/Inertia | API only (no UI) |
| Complexity | Lightweight | Advanced | Low-level |
| Best For | Small to mid projects | Full-stack Laravel apps | Custom authentication systems |
| 2FA / API Tokens | No | Yes | Configurable |
Before going live, consider the following recommendations:
Ensure that you’ve run npm run dev and that your tailwind.config.js includes the correct content paths:
// tailwind.config.js export default { content: [ './resources/**/*.blade.php', './resources/**/*.js', './resources/**/*.vue', ], theme: { extend: {}, }, plugins: [], } Check that RouteServiceProvider::HOME is set properly and that the auth middleware is applied correctly.
This typically happens due to missing CSRF tokens or session expiration. Ensure all forms include @csrf and cookies are being stored.
Let’s build a small dashboard to display user information after login:
// routes/web.php Route::get('/dashboard', function () { return view('dashboard', ['user' => Auth::user()]); })->middleware(['auth', 'verified'])->name('dashboard'); <x-app-layout> <x-slot name="header"> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> {{ __('Dashboard') }} </h2> </x-slot> <div class="py-12"> <div class="max-w-7xl mx-auto sm:px-6 lg:px-8"> <div class="bg-white overflow-hidden shadow-sm sm:rounded-lg"> <div class="p-6 text-gray-900"> {{ __('Hello, ') }} {{ $user->name }}! </div> </div> </div> </div> </x-app-layout> Laravel Breeze provides a perfect balance between simplicity and extensibility. It offers a ready-to-use authentication scaffolding that integrates beautifully with Blade and Tailwind CSS while keeping everything transparent and developer-friendly.
For developers seeking to build modern Laravel apps with authentication, registration, and password reset functionality — without unnecessary complexity — Laravel Breeze is the go-to choice.
From installation to customization, you now have the tools to build a secure and elegant authentication system. Start small, iterate, and customize as your application grows. Breeze ensures your foundation is solid and maintainable.
Final Thought: Laravel Breeze may be the simplest authentication starter kit, but its flexibility and clean architecture make it one of the most powerful tools in the Laravel ecosystem.
Laravel Breeze Tutorial (Blade + Tailwind)
オフショア開発のご紹介資料