Overview: The Shift Toward Code Literacy in 2026 Software development has reached a tipping point where the ability to read and verify code is becoming more valuable than the mechanical act of typing it. Laravel 13 remains the gold standard for PHP development by providing a structured, expressive environment that pairs perfectly with modern AI agents like Claude Code. This guide explores how to build functional web applications—from landing pages to authenticated CRUD systems—using Laravel as the backbone and AI as the engine. The core of the framework revolves around the Model-View-Controller (MVC) architecture. By separating the data logic (Models), the user interface (Views), and the glue that connects them (Controllers), Laravel creates a predictable environment. For developers in 2026, the goal is to understand these architectural pillars so they can direct AI agents effectively and debug the results with precision. Prerequisites and Environment Setup Before launching a new project, you must have a local PHP environment. The most streamlined recommendation is Laravel Herd, a zero-config development environment for macOS and Windows. It handles PHP, web servers, and local domain management effortlessly. Key tools you should have installed: * **PHP 8.3+**: The engine behind Laravel. * **Composer**: The package manager for PHP. * **Node.js & NPM**: Essential for compiling modern CSS and JavaScript. * **Database**: SQLite is the default for zero-config setups, but MySQL is preferred for scaling. Key Libraries & Tools * Laravel 13: The primary PHP framework. * Tailwind CSS 4: A utility-first CSS framework for rapid UI styling, pre-configured in new projects. * Vite: The modern frontend build tool that manages asset compilation. * **Eloquent ORM**: Laravel's built-in database mapper that allows you to interact with data using PHP syntax instead of raw SQL. * **Blade**: The powerful templating engine for generating dynamic HTML. * Pest: The elegant, human-readable testing framework now standard in the ecosystem. * Livewire: A full-stack framework for Laravel that builds dynamic interfaces without leaving the comfort of PHP. Code Walkthrough: Routing and Controllers The entry point for any Laravel request is the `routes/web.php` file. This file maps URLs to specific logic. In a clean architecture, we offload that logic to Controllers. ```php // routes/web.php use App\Http\Controllers\PostController; use Illuminate\Support\Facades\Route; // Basic GET route returning a view Route::get('/', function () { return view('welcome'); }); // Resource routing for CRUD Route::resource('posts', PostController::class); ``` The `Route::resource` command is a shortcut that automatically generates routes for index, create, store, show, edit, update, and destroy actions. Inside the `PostController`, we handle the interaction between the user and the database: ```php // App/Http/Controllers/PostController.php public function index() { // Fetching data via Eloquent $posts = Post::with('category')->latest()->paginate(10); return view('posts.index', compact('posts')); } ``` Database Integration and Eloquent Models Laravel uses Migrations to version-control your database schema. Instead of sharing SQL dumps, you share PHP files that define table structures. To define a relationship, such as a post belonging to a category, we use expressive PHP methods in the Model files. ```php // App/Models/Post.php class Post extends Model { protected $fillable = ['title', 'slug', 'content', 'category_id']; public function category(): BelongsTo { return $this->belongsTo(Category::class); } } ``` To populate these tables with test data, we use Factories and Seeders. Running `php artisan db:seed` allows you to instantly generate hundreds of realistic records, which is crucial for testing UI layouts and pagination. Syntax Notes: Route Model Binding A signature feature of Laravel is Route Model Binding. When you define a route like `/posts/{post}`, and type-hint the `$post` variable in your controller method, Laravel automatically fetches the record from the database. If the ID doesn't exist, it triggers a 404 page immediately without requiring manual `if` checks. Practical Examples 1. **Public Marketing Sites**: Using simple routes and Blade templates to manage high-performance landing pages. 2. **Content Management**: Utilizing Eloquent relationships to link authors, categories, and tags in a blog system. 3. **SaaS Dashboards**: Leveraging starter kits like Laravel Breeze or Jetstream to handle user authentication, profile management, and password resets out of the box. Tips & Gotchas * **Mass Assignment**: Always define `$fillable` or `$guarded` in your models to prevent malicious users from injecting data into fields like `is_admin`. * **Environment Security**: Never commit your `.env` file to version control. It contains sensitive database passwords and API keys. * **The N+1 Problem**: When listing records, use `with('relationship')` to eager load data. Forgetting this can cause your application to run hundreds of unnecessary database queries, tanking performance.
Jetstream
Products
- Mar 20, 2026
- Dec 1, 2025
- Apr 29, 2025
- Mar 4, 2025
- Feb 28, 2025
Overview: Why Modern Starter Kits Matter Building a robust authentication system from scratch is a repetitive, error-prone task that can stall the momentum of a new project. Laravel has long solved this with Breeze and Jetstream, but the latest evolution of Laravel Starter Kits shifts the focus toward modern UI aesthetics and developer experience. These kits aren't just boilerplate; they are a curated selection of industry-best tools like Tailwind CSS V4 and Shadcn UI, providing a professional-grade foundation for SaaS applications. By leveraging these kits, you bypass the hours spent configuring build tools, setting up dark mode, and designing responsive sidebars. Instead, you start with a fully functional, high-fidelity dashboard that is ready for production. This tutorial explores the React and Livewire flavors of these kits, demonstrating how to install, customize, and extend them to fit your specific application needs. Prerequisites To follow along with this guide, you should have a baseline understanding of the following: * **PHP & Laravel:** Basic familiarity with the Laravel framework, including Eloquent models and routing. * **Terminal Usage:** Comfort using the command line to run `composer` and `php artisan` commands. * **Local Development Environment:** Tools like Laravel Herd or Valet to serve your local `.test` sites. * **Frontend Basics:** A working knowledge of either React (for the Inertia kit) or Blade templates (for the Livewire kit). Key Libraries & Tools Before we dive into the code, let's identify the heavy lifters in these new kits: * **Laravel Starter Kits:** The official scaffolding packages for rapid application setup. * **Shadcn UI:** A collection of re-usable components built using Radix UI and Tailwind CSS. Unlike a traditional library, these are copied directly into your project for total control. * **Tailwind CSS V4:** The newest version of the utility-first CSS framework, featuring improved performance and a simplified configuration process. * **Inertia.js V2:** The bridge between Laravel and modern frontend frameworks like React or Vue. * **Livewire & Volt:** A full-stack framework for Laravel that allows you to build dynamic interfaces using PHP. Volt adds an elegant, single-file functional API to Livewire. * **Pest:** A delightful PHP testing framework focused on simplicity and readability. Code Walkthrough: Installing and Customizing React The React starter kit uses Inertia.js to deliver a seamless single-page application (SPA) experience. Let's look at the installation process and how to toggle between different visual layouts. 1. Installation Start by using the Laravel installer to create a new project. You will be prompted to choose your stack. Select React and choose the built-in Laravel authentication unless you specifically need WorkOS integration. ```bash Create a new React project laravel new react-app ``` During installation, you can opt for Pest as your testing framework. The installer uses a "drift" plugin to automatically convert standard PHPUnit tests into the Pest syntax, ensuring your test suite is modern from day one. 2. Switching Layouts in React The new kits include multiple authentication layouts: `Simple`, `Card`, and `Split`. To change the appearance of your login or registration pages, you only need to modify a single import in the Inertia layout file. Navigate to `resources/js/layouts/auth-layout.tsx` (or the equivalent `.js` file). You can swap the layout component being used: ```javascript // resources/js/layouts/auth-layout.tsx // To change to a split layout with a quote and image on the left: import { AuthSplitLayout } from '@/layouts/auth/auth-split-layout'; export default function AuthLayout({ children }) { return <AuthSplitLayout children={children} />; } ``` 3. Adding Shadcn Components Because Shadcn UI components are just files in your `resources` directory, adding new ones is a matter of running an `npx` command. For instance, to add a toggle switch to your dashboard: ```bash npx shadcn-ui@latest add switch ``` Then, import it directly into your dashboard page: ```javascript // resources/js/pages/dashboard.tsx import { Switch } from "@/components/ui/switch"; export default function Dashboard() { return ( <div> <h1>Dashboard</h1> <Switch /> </div> ); } ``` Deep Dive: Livewire, Volt, and Functional PHP If you prefer staying within the PHP ecosystem while maintaining a dynamic frontend, the Livewire kit is the primary choice. This kit heavily utilizes Volt, which allows you to define your component logic and Blade template in the same file. 1. Creating a Volt Component A Volt component represents a modern way to handle state in Laravel. Instead of having a separate Class file and Blade file, everything is co-located. ```bash php artisan make:volt counter ``` This creates a file at `resources/views/livewire/counter.blade.php`. Here is how you write a functional counter using the Volt API: ```php <?php use function Livewire\Volt\{state}; state(['count' => 0]); $increment = fn () => $this->count++; ?> <div> <h1>{{ $count }}</h1> <button wire:click="increment">+</button> </div> ``` 2. Livewire Routing Livewire components can be served as full-page components. In your `routes/web.php`, you can map a URL directly to a Volt component without needing a controller: ```php use Livewire\Volt\Volt; Volt::route('/counter', 'counter'); ``` This approach dramatically reduces the "boilerplate" code required to get a functional page onto the screen. Syntax Notes * **Class Names:** In React components, remember to use `className` instead of `class`. When working with the Split Layout, ensure your text colors (like `text-white`) are applied to visible containers, or they may be obscured by background divs. * **Middleware:** The kits come with `password.confirm` middleware pre-configured. Applying this to a route forces the user to re-enter their password before viewing sensitive settings. * **Email Verification:** To enable mandatory email verification, simply ensure your `User` model implements the `MustVerifyEmail` contract and uncomment the relevant line in your model file. Practical Examples * **SaaS Dashboard:** Use the `SidebarLayout` as the foundation for a multi-tenant dashboard. Since the sidebar is fully customizable, you can easily add dynamic menu items based on the user's subscription tier. * **Marketing Pages:** The `AuthSplitLayout` is perfect for modern landing pages where you want a high-resolution brand image or customer testimonial to sit alongside the sign-up form. * **Internal Tools:** Use the Livewire kit with Shadcn equivalents to build rapid CRUD interfaces. The ability to keep logic and views in a single Volt file makes maintaining dozens of internal forms much easier. Tips & Gotchas * **Asset Watcher:** Always keep `npm run dev` or `vite` running in the background. If your layout changes aren't appearing, it's likely because the asset watcher isn't picking up your file saves. * **Shadcn Portability:** Remember that Shadcn UI isn't a package you update via `composer` or `npm`. If you want the latest version of a component, you generally re-run the `add` command and overwrite the existing file. * **Vue Compatibility:** If you choose the Vue starter kit, be aware that as of early 2025, some Shadcn Vue components may still be catching up to Tailwind CSS V4. Check the official documentation for the latest compatibility patches. * **Testing:** Use Pest to verify your customizations. If you delete a component you think is unused, run `vendor/bin/pest` to ensure you haven't broken a dependency in the authentication flow.
Feb 25, 2025The Power of Frontend-Agnostic Authentication Laravel Fortify serves as the engine under the hood for more prescriptive starter kits like Jetstream. It handles the heavy lifting of security—authentication, registration, and two-factor logic—without forcing a specific UI on you. This makes it the premier choice when you need a custom Tailwind%20UI design or a specialized frontend framework like React or Vue without the overhead of a pre-built starter kit. Prerequisites and Installation To follow along, you should be comfortable with Laravel 10+ and PHP. You'll also need a local development environment. Start by creating a fresh Laravel project and installing the package via Composer. ```bash composer require laravel/fortify php artisan fortify:install ``` This installation publishes several actions into your `app/Actions/Fortify` directory. These are plain PHP classes that handle logic like `CreateNewUser` or `UpdateUserProfile`. Since they live in your app, you can modify them to include extra fields like phone numbers or company IDs easily. Registering Custom Views Because Fortify is "headless," it doesn't know where your login or registration templates live. You must tell Fortify which views to render using the `FortifyServiceProvider`. Inside the `boot` method, use the `Fortify::loginView` and `Fortify::registerView` methods to return your custom Blade templates. ```php Fortify::loginView(function () { return view('auth.login'); }); ``` In your login form, ensure your `action` points to the `login` route and includes a `@csrf` token. Fortify automatically handles the validation and session management once the form is submitted. Implementing Email Verification Securing your application often requires verifying user identity. First, your `User` model must implement the `MustVerifyEmail` interface. Next, enable the feature in `config/fortify.php` by uncommenting `Features::emailVerification()`. Finally, register the view in your provider: ```php Fortify::verifyEmailView(function () { return view('auth.verify-email'); }); ``` By adding the `verified` middleware to your routes, Laravel will automatically redirect unverified users to this view until they click the link sent to their inbox. Handling Password Resets Password recovery is a multi-step process. You need a view to request the reset link and another to actually set the new password. The reset view requires the current `request` object to access the unique reset token. ```php Fortify::resetPasswordView(function ($request) { return view('auth.reset-password', ['request' => $request]); }); ``` In the reset form, you must include a hidden input for the token: `<input type="hidden" name="token" value="{{ $request->route('token') }}">`. This ensures the security handshake between the email link and your database remains intact. Syntax Notes and Best Practices Fortify relies heavily on the **Action Pattern**. Instead of bloated controllers, logic is encapsulated in single-responsibility classes. When customizing, always check `config/fortify.php` first. It controls everything from rate limiting to which features are active. For local email testing, tools like HELO or Mailtrap are indispensable for catching verification and reset emails without sending them to real addresses.
Oct 2, 2024Overview of the Inertia Approach Inertia.js represents a fundamental shift in how we approach the "modern monolith." Historically, developers faced a binary choice: the simplicity of Laravel Blade templates with full page reloads, or the complexity of a fully decoupled Single Page Application (SPA) requiring a custom API. Inertia acts as the glue. It allows you to build a frontend using modern libraries like Vue.js or React while keeping your routing, controllers, and state management firmly in the backend. This eliminates the need for JSON APIs and client-side routing, providing the snappy feel of a desktop app with the productivity of a classic monolith. Prerequisites and Tools To follow this tutorial, you should have a solid grasp of PHP and basic Laravel routing. Familiarity with JavaScript and a component-based framework—specifically Vue.js—is necessary as we explore the frontend implementation. You will need a development environment with Node.js and Composer installed. Key Libraries & Tools * **Laravel**: The backend framework handling logic and data. * **Vue 3**: The reactive frontend library used for UI components. * **Jetstream**: A Laravel starter kit that provides a pre-configured Inertia and Vue environment. * **Vue DevTools**: Essential for inspecting page props and state. * **Network Tab**: Used to monitor XHR requests and partial data transfers. The Core Render Flow In a standard Laravel app, you return `view()`. In an Inertia app, you return `Inertia::render()`. This subtle change is where the magic happens. On the initial request, the server sends a full HTML document. Subsequent requests are intercepted by Inertia, which instructs the server to send back a JSON payload instead. ```php // In your Laravel Controller public function index() { return Inertia::render('TravelStories/Index', [ 'stories' => TravelStory::latest()->get(), ]); } ``` On the frontend, the Vue.js component receives these props automatically. You don't need to fetch data in a `mounted()` hook or manage Axios calls manually. The data is simply there. Navigation and the Link Component Standard `<a>` tags cause full page refreshes, wiping out the application state. To achieve a true SPA feel, you must use the `<Link>` component. ```javascript import { Link } from '@inertiajs/vue3'; // Usage in template <Link href="/statistics" class="btn">View Stats</Link> ``` When you click this link, Inertia makes an XHR request. The server returns only the data needed for the new page, and Inertia swaps the component out without a browser refresh. This reduces the transfer size from dozens of requests to a single, lean JSON payload. Optimizing Data with Partial Reloads Partial reloads allow you to request a subset of data from the server. This is vital for heavy pages where you might only need to update a chart or a list based on a filter. You define these in your controller using closures to ensure they only run when requested. ```php return Inertia::render('Statistics', [ 'chartData' => fn() => $this->getChartData(), 'listData' => Inertia::lazy(fn() => $this->getHeavyData()), ]); ``` By using `Inertia::lazy()`, the data is excluded from the initial page load. You can then trigger a load from the frontend using the `router.reload` method with the `only` attribute: ```javascript router.reload({ only: ['listData'] }); ``` Syntax Notes and Best Practices Always use API Resources to transform your data. Passing raw Eloquent models often exposes sensitive information like email addresses or internal IDs. By using a Resource, you ensure the frontend receives only the slimmed-down data it actually needs for the UI. For data required on every page, such as user permissions or global settings, use the `HandleInertiaRequests` middleware. The `share()` method merges these global props into every single page response, making them accessible via the `usePage()` hook without manual controller injection. Practical Application: Lazy Loading Components A common real-world use case involves heavy dashboards. You can render the page shell immediately to give the user instant feedback, then use a Vue `onMounted` hook to trigger a partial reload for the data-intensive parts. This technique provides the fastest possible perceived performance while keeping your backend logic clean and organized.
Jul 27, 2023