laravel/jetstream
Laravel Jetstream is a starter kit for Laravel 11.x and earlier, providing a ready-made application foundation with common auth and account features. For newer starter kits, see https://laravel.com/starter-kits.
Installation:
composer require laravel/jetstream
php artisan jetstream:install livewire # or inertia for SPA
npm install && npm run dev
php artisan migrate
livewire for traditional server-rendered apps or inertia for modern SPAs.First Use Case:
/register and /login routes to test authentication./dashboard to see the pre-built UI (profile management, teams, etc.).Key Directories:
app/Http/Controllers/Auth/ (Livewire/Inertia controllers).resources/views/ (Blade) or resources/js/Pages/ (Inertia/Vue).app/Models/ (User, Team, etc.).app/Policies/ (Authorization logic).First Customization:
resources/views/auth/login.blade.php).app/Http/Livewire/UpdateProfileInformation.php).LoginController, RegisterController) or extend them.
Example: Custom validation in app/Http/Controllers/Auth/RegisteredUserController.php.auth() helper or AuthenticatesUsers trait. Jetstream includes session management for "remember me" and SSO.// Extend registration logic
public function register(Request $request) {
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => ['required', 'confirmed', 'min:8'],
'terms' => 'accepted', // Custom rule
]);
// ...
}
UpdateProfileInformation or DeleteUser for custom logic.
Example: Add a "bio" field to UpdateProfileInformation.php:
public $bio;
protected $rules = [
'bio' => 'nullable|string|max:500',
];
UpdateProfileInformationForm.vue to include new fields.CreateTeam Livewire component or InviteTeamMember for team-based workflows.
Example: Customize team roles in app/Models/Team.php:
public function addMember(User $user, $role = 'member') {
$this->members()->attach($user->id, ['role' => $role]);
}
TeamPolicy to define custom permissions:
public function delete(Team $team, User $user) {
return $user->id === $team->owner_id;
}
EnableTwoFactorAuthentication Livewire component. Customize recovery codes in app/Models/User.php:
public function recoveryCodes(): HasMany {
return $this->hasMany(RecoveryCode::class);
}
ShowTwoFactorAuthenticationForm to add custom backup logic.app/Http/Controllers/API/ controllers.
Example: Add a custom API endpoint:
Route::middleware('auth:sanctum')->get('/user/profile', function (Request $request) {
return response()->json($request->user()->profile);
});
actingAs, createUser).
Example:
use Laravel\Jetstream\Tests\TestCase;
public function test_profile_update() {
$user = User::factory()->create();
actingAs($user);
$response = put('/user/profile-information', [
'name' => 'New Name',
]);
$response->assertRedirect('/dashboard');
}
Tailwind CSS:
tailwind.config.js to extend Jetstream’s theme. Example:
module.exports = {
theme: {
extend: {
colors: {
primary: '#10B981', // Custom primary color
},
},
},
};
resources/css/app.css.Localization:
php artisan vendor:publish --tag=jetstream-lang
resources/lang/.Notifications:
app/Notifications/ to create custom notifications (e.g., TeamInvitation).Notification facade:
Notification::route('mail', $user->email)
->notify(new TeamInvitation($team));
Event Handling:
Registered, TeamCreated) in EventServiceProvider:
protected $listen = [
'Laravel\Jetstream\Events\Registered' => [
'App\Listeners\LogNewUser',
],
];
Middleware:
app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\VerifyCustomCSP::class,
// ...
],
];
Migration Conflicts:
php artisan migrate after installing Jetstream may fail if you’ve modified users or teams tables.php artisan migrate:fresh --seed
--pretend to preview changes:
php artisan migrate --pretend
Livewire/Inertia Mismatch:
php artisan jetstream:install inertia # or livewire
Team Ownership Logic:
owner_id).TeamPolicy or use accessors:
public function isOwner(User $user) {
return $user->id === $this->owner_id;
}
2FA Recovery Codes:
app/Models/User.php:
public function generateRecoveryCodes() {
$this->recoveryCodes()->delete();
RecoveryCode::generateFor($this);
}
Session Timeout:
config/session.php.driver is set to file, database, or redis:
'driver' => env('SESSION_DRIVER', 'file'),
Vite Asset Loading:
vite.config.js.npm run build
php artisan vite:build for production.Inertia Page Titles:
title prop in Vue components:
<template>
<Head title="Custom Title" />
</template>
Livewire Debugging:
'livewire' => [
'log' => env('APP_DEBUG', false),
],
storage/logs/livewire.log.Inertia Debugging:
Inertia::debug() in middleware to inspect page props:
public function handle(Request $request, Closure $next) {
if (app()->environment('local')) {
Inertia::debug(fn ($view) => [
'url' => $view['url'],
'props' => $view['props'],
]);
}
return $next($request);
}
How can I help you explore Laravel packages today?